Hi i have problem with form embeded.
I have 3 class with relation OneToMany
StockTaking OneToMany StockTakingDetail ManyToOne Hardware
Wheh i submit the form i get error.
I dont know where I made a mistake.
Error:
Catchable Fatal Error: Argument 1 passed to
AppBundle\Entity\MagazineStockTakingDetails::setHardware() must be an
instance of AppBundle\Entity\Hardware, array given, called in
C:\Projekty\sla\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php
on line 442 and defined
Below i past code my class and form. Please help me find mistake.
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Class MagazineStockTaking
* #package AppBundle\Entity
* #ORM\Entity()
* #ORM\Table(name="sla_stocktaking")
*/
class MagazineStockTaking
{
/**
* #ORM\Id
* #ORM\Column(name="stockTakingId", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="stockinNumber", type="string", length=20, nullable=false)
*/
protected $stockingnumber;
/**
* #ORM\Column(name="stockinDate", type="datetime", nullable=false)
*/
protected $stockingdate;
/**
* #ORM\Column(name="stockingNote", type="string", length=1000, nullable=false)
*/
protected $stockingnote;
////////////////////////////////////////////////
// RELACJE
////////////////////////////////////////////////
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Magazine", inversedBy="stocktaking")
* #ORM\JoinColumn(name="magazine_id", referencedColumnName="magazineId", nullable=false)
*/
protected $magazine;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User", inversedBy="stocktaking")
* #ORM\JoinColumn(name="user_id", referencedColumnName="userId", nullable=false)
*/
protected $user;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\MagazineStockTakingDetails", mappedBy="stocktaking", cascade={"persist"})
*/
protected $details;
////////////////////////////////////////////////
// GET SET
////////////////////////////////////////////////
/**
* Constructor
*/
public function __construct()
{
$this->details = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set stockingnumber
*
* #param string $stockingnumber
* #return MagazineStockTaking
*/
public function setStockingnumber($stockingnumber)
{
$this->stockingnumber = $stockingnumber;
return $this;
}
/**
* Get stockingnumber
*
* #return string
*/
public function getStockingnumber()
{
return $this->stockingnumber;
}
/**
* Set stockingdate
*
* #param \DateTime $stockingdate
* #return MagazineStockTaking
*/
public function setStockingdate($stockingdate)
{
$this->stockingdate = $stockingdate;
return $this;
}
/**
* Get stockingdate
*
* #return \DateTime
*/
public function getStockingdate()
{
return $this->stockingdate;
}
/**
* Set stockingnote
*
* #param string $stockingnote
* #return MagazineStockTaking
*/
public function setStockingnote($stockingnote)
{
$this->stockingnote = $stockingnote;
return $this;
}
/**
* Get stockingnote
*
* #return string
*/
public function getStockingnote()
{
return $this->stockingnote;
}
/**
* Set magazine
*
* #param \AppBundle\Entity\Magazine $magazine
* #return MagazineStockTaking
*/
public function setMagazine(\AppBundle\Entity\Magazine $magazine)
{
$this->magazine = $magazine;
return $this;
}
/**
* Get magazine
*
* #return \AppBundle\Entity\Magazine
*/
public function getMagazine()
{
return $this->magazine;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
* #return MagazineStockTaking
*/
public function setUser(\AppBundle\Entity\User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \AppBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Add details
*
* #param \AppBundle\Entity\MagazineStockTakingDetails $details
* #return MagazineStockTaking
*/
public function addDetail(\AppBundle\Entity\MagazineStockTakingDetails $details)
{
$this->details[] = $details;
return $this;
}
/**
* Remove details
*
* #param \AppBundle\Entity\MagazineStockTakingDetails $details
*/
public function removeDetail(\AppBundle\Entity\MagazineStockTakingDetails $details)
{
$this->details->removeElement($details);
}
/**
* Get details
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDetails()
{
return $this->details;
}
}
Second Class
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Class MagazineStockTakingDetails
* #package AppBundle\Entity
* #ORM\Entity()
* #ORM\Table(name="sla_stocktakingdetails")
*/
class MagazineStockTakingDetails
{
/**
* #ORM\Id()
* #ORM\Column(name="stackTakingDetailsId", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="hardwareCount", type="integer", nullable=false)
*/
protected $count = 1;
/////////////////////////////////////////////
// RELACJE
/////////////////////////////////////////////
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\MagazineStockTaking", inversedBy="details")
* #ORM\JoinColumn(name="stacktaking_id", referencedColumnName="stockTakingId", nullable=false)
*/
protected $stocktaking;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Hardware", inversedBy="stocktakingdetails",cascade={"persist"})
* #ORM\JoinColumn(name="hardware_id", referencedColumnName="hardwareId", nullable=false)
*/
protected $hardware;
/////////////////////////////////////////////
// GET SET
/////////////////////////////////////////////
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set count
*
* #param integer $count
* #return MagazineStockTakingDetails
*/
public function setCount($count)
{
$this->count = $count;
return $this;
}
/**
* Get count
*
* #return integer
*/
public function getCount()
{
return $this->count;
}
/**
* Set stocktaking
*
* #param \AppBundle\Entity\MagazineStockTaking $stocktaking
* #return MagazineStockTakingDetails
*/
public function setStocktaking(\AppBundle\Entity\MagazineStockTaking $stocktaking)
{
$this->stocktaking = $stocktaking;
return $this;
}
/**
* Get stocktaking
*
* #return \AppBundle\Entity\MagazineStockTaking
*/
public function getStocktaking()
{
return $this->stocktaking;
}
/**
* Set hardware
*
* #param \AppBundle\Entity\Hardware $hardware
* #return MagazineStockTakingDetails
*/
public function setHardware(\AppBundle\Entity\Hardware $hardware)
{
$this->hardware = $hardware;
return $this;
}
/**
* Get hardware
*
* #return \AppBundle\Entity\Hardware
*/
public function getHardware()
{
return $this->hardware;
}
}
Third Class
<?php
namespace AppBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;
use JMS\Serializer\Annotation\Groups;
/**
* Class Hardware
* #package AppBundle\Entity
* #ORM\Entity(repositoryClass="HardwareRepository", )
* #ORM\Table(name="sla_hardwares")
* #JMS\ExclusionPolicy("all")
*/
class Hardware
{
/**
* #ORM\Id()
* #ORM\Column(name="hardwareId", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(name="hardwareSn", type="string", length=200, nullable=true)
*/
protected $sn;
/**
* #ORM\Column(name="hardwareGwarantyDate", type="datetime", nullable=true)
*/
protected $gwarantydate;
/**
* #ORM\Column(name="hardwareNote", type="string", length=750, nullable=true)
*/
protected $note;
/**
* #ORM\Column(name="hardwareIsReturned", type="boolean", nullable=false)
*/
protected $isreturned = false;
////////////////////////////////////////
//// RELACJE
////////////////////////////////////////
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\HardwareProducent", inversedBy="hardware")
* #ORM\JoinColumn(name="producent_id", referencedColumnName="producentId", nullable=false)
*/
protected $producent;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\HardwareCategory", inversedBy="hardware")
* #ORM\JoinColumn(name="category_id", referencedColumnName="hardwareCategoryId", nullable=false)
*/
protected $category;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\HardwareModel", inversedBy="hardware")
* #ORM\JoinColumn(name="model_id", referencedColumnName="hardwareModelId", nullable=false)
*/
protected $model;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\HardwareStatus", inversedBy="hardware")
* #ORM\JoinColumn(name="status_id", referencedColumnName="statusId", nullable=false)
*/
protected $status;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\HardwareStatusHistory", mappedBy="hardware")
*/
protected $statushistory;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\MagazineDetails", mappedBy="hardware")
*/
protected $magazine;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\MagazineShiftDetails", mappedBy="hardware")
*/
protected $magazineshift;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\MagazineUtilizeDetails", mappedBy="hardware")
*/
protected $utilize;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\MagazineStockTakingDetails", mappedBy="hardware", cascade={"persist"})
*/
protected $stocktakingdetails;
////////////////////////////////////////
//// GET SET
////////////////////////////////////////
/**
* Constructor
*/
public function __construct()
{
$this->statushistory = new \Doctrine\Common\Collections\ArrayCollection();
$this->magazine = new \Doctrine\Common\Collections\ArrayCollection();
$this->magazineshift = new \Doctrine\Common\Collections\ArrayCollection();
$this->utilize = new \Doctrine\Common\Collections\ArrayCollection();
$this->stocktakingdetails = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set sn
*
* #param string $sn
* #return Hardware
*/
public function setSn($sn)
{
$this->sn = $sn;
return $this;
}
/**
* Get sn
*
* #return string
*/
public function getSn()
{
return $this->sn;
}
/**
* Set gwarantydate
*
* #param \DateTime $gwarantydate
* #return Hardware
*/
public function setGwarantydate($gwarantydate)
{
$this->gwarantydate = $gwarantydate;
return $this;
}
/**
* Get gwarantydate
*
* #return \DateTime
*/
public function getGwarantydate()
{
return $this->gwarantydate;
}
/**
* Set note
*
* #param string $note
* #return Hardware
*/
public function setNote($note)
{
$this->note = $note;
return $this;
}
/**
* Get note
*
* #return string
*/
public function getNote()
{
return $this->note;
}
/**
* Set isreturned
*
* #param boolean $isreturned
* #return Hardware
*/
public function setIsreturned($isreturned)
{
$this->isreturned = $isreturned;
return $this;
}
/**
* Get isreturned
*
* #return boolean
*/
public function getIsreturned()
{
return $this->isreturned;
}
/**
* Set producent
*
* #param \AppBundle\Entity\HardwareProducent $producent
* #return Hardware
*/
public function setProducent(\AppBundle\Entity\HardwareProducent $producent)
{
$this->producent = $producent;
return $this;
}
/**
* Get producent
*
* #return \AppBundle\Entity\HardwareProducent
*/
public function getProducent()
{
return $this->producent;
}
/**
* Set category
*
* #param \AppBundle\Entity\HardwareCategory $category
* #return Hardware
*/
public function setCategory(\AppBundle\Entity\HardwareCategory $category)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return \AppBundle\Entity\HardwareCategory
*/
public function getCategory()
{
return $this->category;
}
/**
* Set model
*
* #param \AppBundle\Entity\HardwareModel $model
* #return Hardware
*/
public function setModel(\AppBundle\Entity\HardwareModel $model)
{
$this->model = $model;
return $this;
}
/**
* Get model
*
* #return \AppBundle\Entity\HardwareModel
*/
public function getModel()
{
return $this->model;
}
/**
* Set status
*
* #param \AppBundle\Entity\HardwareStatus $status
* #return Hardware
*/
public function setStatus(\AppBundle\Entity\HardwareStatus $status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return \AppBundle\Entity\HardwareStatus
*/
public function getStatus()
{
return $this->status;
}
/**
* Add statushistory
*
* #param \AppBundle\Entity\HardwareStatusHistory $statushistory
* #return Hardware
*/
public function addStatushistory(\AppBundle\Entity\HardwareStatusHistory $statushistory)
{
$this->statushistory[] = $statushistory;
return $this;
}
/**
* Remove statushistory
*
* #param \AppBundle\Entity\HardwareStatusHistory $statushistory
*/
public function removeStatushistory(\AppBundle\Entity\HardwareStatusHistory $statushistory)
{
$this->statushistory->removeElement($statushistory);
}
/**
* Get statushistory
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getStatushistory()
{
return $this->statushistory;
}
/**
* Add magazine
*
* #param \AppBundle\Entity\MagazineDetails $magazine
* #return Hardware
*/
public function addMagazine(\AppBundle\Entity\MagazineDetails $magazine)
{
$this->magazine[] = $magazine;
return $this;
}
/**
* Remove magazine
*
* #param \AppBundle\Entity\MagazineDetails $magazine
*/
public function removeMagazine(\AppBundle\Entity\MagazineDetails $magazine)
{
$this->magazine->removeElement($magazine);
}
/**
* Get magazine
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getMagazine()
{
return $this->magazine;
}
/**
* Add magazineshift
*
* #param \AppBundle\Entity\MagazineShiftDetails $magazineshift
* #return Hardware
*/
public function addMagazineshift(\AppBundle\Entity\MagazineShiftDetails $magazineshift)
{
$this->magazineshift[] = $magazineshift;
return $this;
}
/**
* Remove magazineshift
*
* #param \AppBundle\Entity\MagazineShiftDetails $magazineshift
*/
public function removeMagazineshift(\AppBundle\Entity\MagazineShiftDetails $magazineshift)
{
$this->magazineshift->removeElement($magazineshift);
}
/**
* Get magazineshift
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getMagazineshift()
{
return $this->magazineshift;
}
/**
* Add utilize
*
* #param \AppBundle\Entity\MagazineUtilizeDetails $utilize
* #return Hardware
*/
public function addUtilize(\AppBundle\Entity\MagazineUtilizeDetails $utilize)
{
$this->utilize[] = $utilize;
return $this;
}
/**
* Remove utilize
*
* #param \AppBundle\Entity\MagazineUtilizeDetails $utilize
*/
public function removeUtilize(\AppBundle\Entity\MagazineUtilizeDetails $utilize)
{
$this->utilize->removeElement($utilize);
}
/**
* Get utilize
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUtilize()
{
return $this->utilize;
}
/**
* Add stocktakingdetails
*
* #param \AppBundle\Entity\MagazineStockTakingDetails $stocktakingdetails
* #return Hardware
*/
public function addStocktakingdetail(\AppBundle\Entity\MagazineStockTakingDetails $stocktakingdetails)
{
$this->stocktakingdetails[] = $stocktakingdetails;
$stocktakingdetails->setHardware($this);
return $this;
}
/**
* Remove stocktakingdetails
*
* #param \AppBundle\Entity\MagazineStockTakingDetails $stocktakingdetails
*/
public function removeStocktakingdetail(\AppBundle\Entity\MagazineStockTakingDetails $stocktakingdetails)
{
$this->stocktakingdetails->removeElement($stocktakingdetails);
}
/**
* Get stocktakingdetails
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getStocktakingdetails()
{
return $this->stocktakingdetails;
}
}
First Form Class
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class StockTakingFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('stockingnote','textarea',array(
'label' => false,
'attr' => array(
'class' => 'gui-textarea',
'placeholder' => 'Uwagi',
'data-text' => 'Uwagi'
),
'required' => false
))
->add('details','collection',array(
'type' => new StockTakingDetailFormType(),
'allow_add' => true,
'by_reference' => false
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\MagazineStockTaking',
'attr' => array(
'id' => 'form_stoking'
)
));
}
public function getName() {
return 'stocktaking';
}
}
Second Form Class
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class StockTakingDetailFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('count','number',array(
'label' => false,
'data' => '1',
'required' => false
))
->add('hardware','collection',array(
'type' => new HardwareFormType(),
'allow_add' => true,
'by_reference' => false
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\MagazineStockTakingDetails'
));
}
public function getName()
{
return 'stocktakingtetail';
}
}
Third Form Class
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class HardwareFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('sn','text',array(
'label' => false,
'attr' => array(
'class' => 'gui-input',
'placeholder' => 'Numer Seryjny Urządzenia'
),
'required' => true
))
->add('gwarantydate','number',array(
'label' => false,
'attr' => array(
'class' => 'gui-input',
'placeholder' => 'Ilość Gwarancji (miesięcy)'
),
'required' => false
))
->add('isreturned','checkbox',array(
'label' => 'Sprzęt Rotacyjny',
'label_attr' => array(
'class' => 'option-primary'
),
'required' => true
))
->add('note','textarea' ,array(
'label' => false,
'attr' => array(
'class' => 'gui-textarea',
'placeholder' => 'Opis',
'data-text' => 'Opis'
),
'required' => false
))
->add('producent','entity',array(
'class' => 'AppBundle\Entity\HardwareProducent',
'property' => 'name',
'label' => false,
'attr' => array(
'class' => 'select',
'placeholder' => 'Producent'
),
'required' => true
))
->add('category','entity',array(
'class' => 'AppBundle\Entity\HardwareCategory',
'property' => 'name',
'label' => false,
'attr' => array(
'class' => 'select',
'placeholder' => 'Kategoria'
),
'required' => true
))
->add('model','entity',array(
'class' => 'AppBundle\Entity\HardwareModel',
'property' => 'name',
'label' => false,
'attr' => array(
'class' => 'select',
'placeholder' => 'Model'
),
'required' => true
))
->add('status','entity',array(
'class' => 'AppBundle\Entity\HardwareStatus',
'property' => 'name',
'label' => false,
'attr' => array(
'class' => 'select',
'placeholder' => 'Status'
),
'required' => true
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Hardware'
));
}
public function getName()
{
return 'hardware';
}
}
If you have a ManyToOne on the hardware the MagazineStockTakingDetails has a reference to an object of the type Hardware, therefore you can only set one object of the type hardware, but you are trying to set an ArrayCollection.
This can't work:
->add('hardware','collection',array(
'type' => new HardwareFormType(),
'allow_add' => true,
'by_reference' => false
))
You will need to do something like this:
->add('hardware', new HardwareFormType(),array(
...
))
Related
I have this problem when i execute my project, I use FormEvent in FormType
entity Departement.php:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Departement
*
* #ORM\Table(name="departement")
* #ORM\Entity(repositoryClass="AppBundle\Repository\DepartementRepository")
*/
class Departement
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var int
*
* #ORM\Column(name="code", type="integer")
*/
private $code;
/**
*#ORM\ManyToOne(targetEntity="AppBundle\Entity\Region")
*/
private $region;
/**
*#ORM\OneToMany(targetEntity="AppBundle\Entity\Ville", mappedBy="departement")
*/
private $villes;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Departement
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set code
*
* #param integer $code
* #return Departement
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return integer
*/
public function getCode()
{
return $this->code;
}
/**
* Constructor
*/
public function __construct()
{
$this->villes = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Set region
*
* #param \AppBundle\Entity\Region $region
* #return Departement
*/
public function setRegion(\AppBundle\Entity\Region $region = null)
{
$this->region = $region;
return $this;
}
/**
* Get region
*
* #return \AppBundle\Entity\Region
*/
public function getRegion()
{
return $this->region;
}
/**
* Add villes
*
* #param \AppBundle\Entity\Ville $villes
* #return Departement
*/
public function addVille(\AppBundle\Entity\Ville $villes)
{
$this->villes[] = $villes;
return $this;
}
/**
* Remove villes
*
* #param \AppBundle\Entity\Ville $villes
*/
public function removeVille(\AppBundle\Entity\Ville $villes)
{
$this->villes->removeElement($villes);
}
/**
* Get villes
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getVilles()
{
return $this->villes;
}
public function __toString(){
return $this->name;
}
}
entity ville.php:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Ville
*
* #ORM\Table(name="ville")
* #ORM\Entity(repositoryClass="AppBundle\Repository\VilleRepository")
*/
class Ville
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #var int
*
* #ORM\Column(name="code", type="integer")
*/
private $code;
/**
*#ORM\ManyToOne(targetEntity="AppBundle\Entity\Departement")
*/
private $departement;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Ville
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set code
*
* #param integer $code
* #return Ville
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return integer
*/
public function getCode()
{
return $this->code;
}
/**
* Set departement
*
* #param \AppBundle\Entity\Departement $departement
* #return Ville
*/
public function setDepartement(\AppBundle\Entity\Departement $departement = null)
{
$this->departement = $departement;
return $this;
}
/**
* Get departement
*
* #return \AppBundle\Entity\Departement
*/
public function getDepartement()
{
return $this->departement;
}
public function __toString(){
return $this->name;
}
}
Form MedecinType.php:
<?php
namespace AppBundle\Form;
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\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormInterface;
use AppBundle\Entity\Region;
use AppBundle\Entity\Departement;
use AppBundle\Entity\Ville;
class MedecinType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('region', EntityType::class, [
'class' => 'AppBundle\Entity\Region',
'placeholder' => 'Sélectionnez votre région',
'mapped' => false,
'required' => false
]);
$builder->get('region')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) {
$form = $event->getForm();
$this->addDepartementField($form->getParent(), $form->getData());
}
);
}
private function addDepartementField(FormInterface $form, Region $region)
{
$builder = $form->getConfig()->getFormFactory()->createNamedBuilder(
'departement',
EntityType::class,
null,
[
'class' => 'AppBundle\Entity\Departement',
'placeholder' => 'Sélectionnez votre département',
'mapped' => false,
'required' => false,
'auto_initialize' => false,
'choices' => $region->getDepartements()
]);
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) {
$form= $event->getForm();
$this->addVilleField($form->getParent(), $form->getData());
}
);
$form->add($builder->getForm());
}
private function addVilleField(FormInterface $form, Departement $departement)
{
$form->add('ville', EntityType::class, [
'class' => 'AppBundle\Entity\Ville',
'placeholder' => 'Sélectionnez votre ville',
'choices' => $departement->getVilles()
]);
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Medecin'
));
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_medecin';
}
}
help me please for resolve this problem and thank you advanced
Since you've set departement field as nullable with 'required' => false,, the method $form->getData() in event listener may be either an instance of Departement entity or null if no departement was chosen.
You have to check if $form->getData() returns instance of your entity and
handle if it's not.
That would be something like:
$builder->addEventListener(
FormEvents::POST_SUBMIT,
function(FormEvent $event) {
$form= $event->getForm();
$formData = $form->getData();
if(! $formData instanceof Departement) {
//handle this case or just do nothing and return from the listener
return;
}
// here's the default case
$this->addVilleField($form->getParent(), $form->getData());
}
);
I have symfony form with choice field. I want to load choices from my entity class static method. can i use data or CallbackChoiceLoader? what is the best practise?
this is my field:
class CarType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', ChoiceType::class, [
// This choices I would like to load from:
// 'choices' => $car::getTypes(),
'choices' => [
'Critical' => 'critical',
'Medium' => 'medium',
'Info' => 'info',
],
'label' => 'Type'
])
->add('name', TextType::class, [
'label' => 'Name'
])
->add('save', SubmitType::class, [
'label' => 'Save'
])
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Car'
]);
}
public function getName()
{
return 'car';
}
}
This is my entity:
/**
* #ORM\Entity
* #ORM\Table(name="car")
*/
class Car
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string $type
*
* #Assert\NotBlank()
* #ORM\Column(name="type")
*/
private $type;
/**
* #var string $name
*
* #Assert\NotBlank()
* #ORM\Column(name="name")
*/
private $name;
/**
* #var \DateTime $created
*
* #ORM\Column(name="created", type="datetime")
*/
private $created;
private static $types = ['main', 'custom'];
public function __construct()
{
$this->created = new \DateTime('now', new \DateTimeZone('Europe/Ljubljana'));
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get types
*
* #return array
*/
public function getTypes()
{
return self::$types;
}
/**
* Set type
*
* #param string $type
*
* #return Car
*/
public function setType($type)
{
if (in_array($type, $this->getTypes())) {
$this->type = $type;
}
return $this;
}
/**
* Get type
*
* #return string
*/
public function getType()
{
return $this->type;
}
/**
* Set name
*
* #param string $name
*
* #return Car
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set created
*
* #param \DateTime $created
*
* #return Car
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* #return \DateTime
*/
public function getCreated()
{
return $this->created;
}
How and what can i use to load choices from $car::getTypes() method like i commented in form so that the choices are loaded dynamicly based on values in getTypes entity method?
Edit: This is option 1. Option 2 below more directly answers the question.
The preferred method of creating a choice form field from an entity is to use the EntityType field. Here is an example from an application that requires an ethnicity field. Below that is the Ethnicity entity.
form field:
->add('ethnicity', EntityType::class, array(
'label' => 'Ethnicity:',
'class' => 'AppBundle:Ethnicity',
'choice_label' => 'abbreviation',
'expanded' => false,
'placeholder' => 'Select ethnicity',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('e')
->orderBy('e.abbreviation', 'ASC')
;
},
))
Ethnicity entity:
/**
* Ethnicity.
*
* #ORM\Table(name="ethnicity")
* #ORM\Entity
*/
class Ethnicity
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="ethnicity", type="string", length=45, nullable=true)
*/
protected $ethnicity;
/**
* #var string
*
* #ORM\Column(name="abbr", type="string", length=45, nullable=true)
*/
protected $abbreviation;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\OneToMany(targetEntity="AppBundle\Entity\Member", mappedBy="ethnicity", cascade={"persist"})
*/
protected $members;
/**
* Constructor.
*/
public function __construct()
{
$this->members = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set ethnicity.
*
* #param string $ethnicity
*
* #return Ethnicity
*/
public function setEthnicity($ethnicity)
{
$this->ethnicity = $ethnicity;
return $this;
}
/**
* Get ethnicity.
*
* #return string
*/
public function getEthnicity()
{
return $this->ethnicity;
}
/**
* Set abbreviation.
*
* #param string $abbreviation
*
* #return Ethnicity
*/
public function setAbbreviation($abbreviation)
{
$this->abbreviation = $abbreviation;
return $this;
}
/**
* Get abbreviation.
*
* #return string
*/
public function getAbbreviation()
{
return $this->abbreviation;
}
/**
* Add members.
*
* #param \AppBundle\Entity\Member $members
*
* #return Ethnicity
*/
public function addMember(\AppBundle\Entity\Member $members)
{
$this->members[] = $members;
return $this;
}
/**
* Remove members.
*
* #param \AppBundle\Entity\Member $members
*/
public function removeMember(\Truckee\ProjectmanaBundle\Entity\Member $members)
{
$this->members->removeElement($members);
}
/**
* Get members.
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getMembers()
{
return $this->members;
}
/**
* #var bool
*
* #ORM\Column(name="enabled", type="boolean", nullable=true)
*/
protected $enabled;
/**
* Set enabled.
*
* #param bool $enabled
*
* #return enabled
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
return $this;
}
/**
* Get enabled.
*
* #return bool
*/
public function getEnabled()
{
return $this->enabled;
}
}
Option 2:
If you really want to do that, then here's an approach:
Modify your static property $types such that the choices are values in an array, e.g., $types = array(1 => 'main', 2 => 'custom')
In your controller, add a use statement for the Car entity.
In controller action:
$car = new Car();
$types = $car->getTypes;
Use the answer to Passing data to buildForm() in Symfony 2.8/3.0 to see how to pass $types to your form.
I have an Organisation entity referencing an embedded form containing a Country entity. The form saves without issue, but the Country EntityType field does not correctly pick up the value upon editing, and as such the first option in the dropdown is always selected rather than the correct option.
The OrganisationType form:
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrganisationType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', new TitleType(),
array('required' => true, 'label' => false))
->add('country', new CountryType(), array('label' => false))
->add('location', 'text',
array('required' => false, 'label' => 'City'));
}
public function getName()
{
return 'organisation';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Organisation',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'organisation',
'cascade_validation' => true
));
}
}
The CountryType form:
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
class CountryType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', EntityType::class, array(
'label' => 'Country',
'class' => 'AppBundle:Country',
'choice_label' => 'name',
'placeholder' => 'Choose an option...',
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('c')->orderBy('c.name', 'ASC');
}
));
}
public function getName()
{
return 'country';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Country'
));
}
}
Organisation Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Gedmo\Mapping\Annotation as Gedmo;
use AppBundle\Model\OrganisationModel;
/**
* Organisation
*
* #ORM\Table(name="organisation", indexes={#ORM\Index(name="fk_meta_org_country_idx", columns={"country_id"}), #ORM\Index(name="fk_meta_org_subdivision_idx", columns={"country_subdivision_id"}), #ORM\Index(name="fk_meta_org_user_entered_idx", columns={"entered_by_user_id"}), #ORM\Index(name="fk_meta_org_user_updated_idx", columns={"updated_by_user_id"}), #ORM\Index(name="fk_meta_org_title_idx", columns={"title_id"})})
* #ORM\Entity(repositoryClass="AppBundle\Entity\OrganisationRepository")
*/
class Organisation extends OrganisationModel
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="location", type="string", length=45, nullable=false)
*/
private $location;
/**
* #var boolean
*
* #ORM\Column(name="hidden", type="boolean", nullable=false)
*/
private $hidden;
/**
* #var \DateTime
*
* #ORM\Column(name="date_entered", type="datetime", nullable=false)
* #Gedmo\Timestampable(on="create")
*/
private $dateEntered;
/**
* #var \DateTime
*
* #ORM\Column(name="date_updated", type="datetime", nullable=false)
* #Gedmo\Timestampable(on="update")
*/
private $dateUpdated;
/**
* #var \AppBundle\Entity\Country
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Country")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_id", referencedColumnName="id")
* })
*/
private $country;
/**
* #var \AppBundle\Entity\CountrySubdivision
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\CountrySubdivision")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="country_subdivision_id", referencedColumnName="id")
* })
*/
private $countrySubdivision;
/**
* #var \AppBundle\Entity\Title
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Title", cascade="persist")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="title_id", referencedColumnName="id")
* })
* #Assert\Type(type="AppBundle\Entity\Title")
* #Assert\Valid()
*/
private $title;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="entered_by_user_id", referencedColumnName="id")
* })
*/
private $enteredByUser;
/**
* #var \AppBundle\Entity\User
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="updated_by_user_id", referencedColumnName="id")
* })
*/
private $updatedByUser;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set location
*
* #param string $location
* #return Organisation
*/
public function setLocation($location)
{
$this->location = $location;
return $this;
}
/**
* Get location
*
* #return string
*/
public function getLocation()
{
return $this->location;
}
/**
* Set hidden
*
* #param boolean $hidden
* #return Organisation
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get hidden
*
* #return boolean
*/
public function getHidden()
{
return $this->hidden;
}
/**
* Set dateEntered
*
* #param \DateTime $dateEntered
* #return Organisation
*/
public function setDateEntered($dateEntered)
{
$this->dateEntered = $dateEntered;
return $this;
}
/**
* Get dateEntered
*
* #return \DateTime
*/
public function getDateEntered()
{
return $this->dateEntered;
}
/**
* Set dateUpdated
*
* #param \DateTime $dateUpdated
* #return Organisation
*/
public function setDateUpdated($dateUpdated)
{
$this->dateUpdated = $dateUpdated;
return $this;
}
/**
* Get dateUpdated
*
* #return \DateTime
*/
public function getDateUpdated()
{
return $this->dateUpdated;
}
/**
* Set country
*
* #param \AppBundle\Entity\Country $country
* #return Organisation
*/
public function setCountry(\AppBundle\Entity\Country $country = null)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* #return \AppBundle\Entity\Country
*/
public function getCountry()
{
return $this->country;
}
/**
* Set countrySubdivision
*
* #param \AppBundle\Entity\CountrySubdivision $countrySubdivision
* #return Organisation
*/
public function setCountrySubdivision(\AppBundle\Entity\CountrySubdivision $countrySubdivision = null)
{
$this->countrySubdivision = $countrySubdivision;
return $this;
}
/**
* Get countrySubdivision
*
* #return \AppBundle\Entity\CountrySubdivision
*/
public function getCountrySubdivision()
{
return $this->countrySubdivision;
}
/**
* Set title
*
* #param \AppBundle\Entity\Title $title
* #return Organisation
*/
public function setTitle(\AppBundle\Entity\Title $title = null)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return \AppBundle\Entity\Title
*/
public function getTitle()
{
return $this->title;
}
/**
* Set enteredByUser
*
* #param \AppBundle\Entity\User $enteredByUser
* #return Organisation
*/
public function setEnteredByUser(\AppBundle\Entity\User $enteredByUser = null)
{
$this->enteredByUser = $enteredByUser;
return $this;
}
/**
* Get enteredByUser
*
* #return \AppBundle\Entity\User
*/
public function getEnteredByUser()
{
return $this->enteredByUser;
}
/**
* Set updatedByUser
*
* #param \AppBundle\Entity\User $updatedByUser
* #return Organisation
*/
public function setUpdatedByUser(\AppBundle\Entity\User $updatedByUser = null)
{
$this->updatedByUser = $updatedByUser;
return $this;
}
/**
* Get updatedByUser
*
* #return \AppBundle\Entity\User
*/
public function getUpdatedByUser()
{
return $this->updatedByUser;
}
}
Country Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
/**
* Country
*
* #ORM\Table(name="country", uniqueConstraints={#ORM\UniqueConstraint(name="unique", columns={"code"})})
* #ORM\Entity(repositoryClass="AppBundle\Entity\CountryRepository")
*/
class Country
{
/**
* #var string
*
* #ORM\Column(name="code", type="string", length=2, nullable=false)
*/
private $code;
/**
* #var string
*
* #ORM\Column(name="code_iso_3", type="string", length=3, nullable=true)
*/
private $codeIso3;
/**
* #var string
*
* #ORM\Column(name="code_iso_numeric", type="string", length=4, nullable=true)
*/
private $codeIsoNumeric;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="capital", type="string", length=30, nullable=true)
*/
private $capital;
/**
* #var string
*
* #ORM\Column(name="continent_name", type="string", length=15, nullable=true)
*/
private $continentName;
/**
* #var string
*
* #ORM\Column(name="continent_code", type="string", length=2, nullable=true)
*/
private $continentCode;
/**
* #var boolean
*
* #ORM\Column(name="hidden", type="boolean", nullable=false)
*/
private $hidden;
/**
* #var \DateTime
*
* #ORM\Column(name="date_entered", type="datetime", nullable=false)
*/
private $dateEntered;
/**
* #var \DateTime
*
* #ORM\Column(name="date_updated", type="datetime", nullable=false)
*/
private $dateUpdated;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="CountrySubdivision", mappedBy="country")
*/
private $subdivisions;
/*
* #var AppBundle\Entity\CountrySubdivision
* Stored purely for the purposes of form capture
*/
private $subdivision;
/**
* #var Doctrine\Common\Collections\ArrayCollection
*
* #ORM\OneToMany(targetEntity="CountrySubdivisionType", mappedBy="country")
*/
private $subdivisionTypes;
public function __construct()
{
$this->subdivisions = new ArrayCollection();
$this->subdivisionTypes = new ArrayCollection();
}
public function getSubdivisions()
{
return $this->subdivisions->toArray();
}
public function getSubdivisionsOfParentId($parentId)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq("parentId", $parentId))
->orderBy(array("name" => Criteria::ASC));
return $this->subdivisions->matching($criteria)->toArray();
}
public function setSubdivisions($subdivisions)
{
}
public function getSubdivision()
{
return $this->subdivision;
}
public function setSubdivision($subdivision)
{
$this->subdivision = $subdivision;
}
public function setId($id)
{
$this->id = $id;
}
public function getSubdivisionTypeOfParentId($parentId)
{
$criteria = Criteria::create()
->where(Criteria::expr()->eq("subdivisionId", $parentId))
->orderBy(array("name" => Criteria::ASC));
return $this->subdivisionTypes->matching($criteria)[0];
}
/**
* Set code
*
* #param string $code
* #return Country
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* #return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set codeIso3
*
* #param string $codeIso3
* #return Country
*/
public function setCodeIso3($codeIso3)
{
$this->codeIso3 = $codeIso3;
return $this;
}
/**
* Get codeIso3
*
* #return string
*/
public function getCodeIso3()
{
return $this->codeIso3;
}
/**
* Set codeIsoNumeric
*
* #param string $codeIsoNumeric
* #return Country
*/
public function setCodeIsoNumeric($codeIsoNumeric)
{
$this->codeIsoNumeric = $codeIsoNumeric;
return $this;
}
/**
* Get codeIsoNumeric
*
* #return string
*/
public function getCodeIsoNumeric()
{
return $this->codeIsoNumeric;
}
/**
* Set name
*
* #param string $name
* #return Country
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set capital
*
* #param string $capital
* #return Country
*/
public function setCapital($capital)
{
$this->capital = $capital;
return $this;
}
/**
* Get capital
*
* #return string
*/
public function getCapital()
{
return $this->capital;
}
/**
* Set continentName
*
* #param string $continentName
* #return Country
*/
public function setContinentName($continentName)
{
$this->continentName = $continentName;
return $this;
}
/**
* Get continentName
*
* #return string
*/
public function getContinentName()
{
return $this->continentName;
}
/**
* Set continentCode
*
* #param string $continentCode
* #return Country
*/
public function setContinentCode($continentCode)
{
$this->continentCode = $continentCode;
return $this;
}
/**
* Get continentCode
*
* #return string
*/
public function getContinentCode()
{
return $this->continentCode;
}
/**
* Set hidden
*
* #param boolean $hidden
* #return Country
*/
public function setHidden($hidden)
{
$this->hidden = $hidden;
return $this;
}
/**
* Get hidden
*
* #return boolean
*/
public function getHidden()
{
return $this->hidden;
}
/**
* Set dateEntered
*
* #param \DateTime $dateEntered
* #return Country
*/
public function setDateEntered($dateEntered)
{
$this->dateEntered = $dateEntered;
return $this;
}
/**
* Get dateEntered
*
* #return \DateTime
*/
public function getDateEntered()
{
return $this->dateEntered;
}
/**
* Set dateUpdated
*
* #param \DateTime $dateUpdated
* #return Country
*/
public function setDateUpdated($dateUpdated)
{
$this->dateUpdated = $dateUpdated;
return $this;
}
/**
* Get dateUpdated
*
* #return \DateTime
*/
public function getDateUpdated()
{
return $this->dateUpdated;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
}
If I replace, in the CountryType form...
->add('id', EntityType::class, ...
With...
->add('name')
...then I see the country name displayed without any issue. Where am I going wrong with the EntityType?
I think you're not using custom FormType correctly. You're not supposed to add anything to the builder in a custom FormType. Try this :
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
class OrganisationType extends AbstractType
{
public function __construct()
{
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', new TitleType(),
array('required' => true, 'label' => false))
->add('country', new CountryType(), array(
'label' => 'Country',
'choice_label' => 'name',
'placeholder' => 'Choose an option...',
'query_builder' => function (EntityRepository $repository) {
return $repository->createQueryBuilder('c')->orderBy('c.name', 'ASC');
}
))
->add('location', 'text',
array('required' => false, 'label' => 'City'));
}
public function getName()
{
return 'organisation';
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Organisation',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'organisation',
'cascade_validation' => true
));
}
}
with
<?php
namespace AppBundle\Form\Type\Meta;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;
class CountryType extends AbstractType
{
public function getName()
{
return 'country';
}
public function getParent()
{
return EntityType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Country'
));
}
}
I have a project working with sonata AdminBundle and I want to use the mediaBundle for the upload. I have an entity prototype that can have many images. I would like to have a form so I can add many images before saving.
I followed the steps in MediaBundle ~ MediaType improved
But it doesn't work and I don't understand why !
EDIT :
To be clear : I have 3 sections and I would like to be able to upload many images in each one of them.
Here is my prototype entity :
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Prototype
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\PrototypeRepository")
* #Vich\Uploadable
* #ORM\HasLifecycleCallbacks
*/
class Prototype
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom", type="string", length=255)
*/
private $nom;
/**
* #var string
*
* #ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* #var \DateTime
*
* #ORM\Column(name="dateCreation", type="date")
*/
private $dateCreation;
/**
* #ORM\Column(type="string", length=255, name="fichier_nom")
*
* #var string $nomFichier
*/
public $nomFichier;
/**
* #ORM\Column(type="datetime")
*
* #var \DateTime $updatedAt
*/
public $updatedAt;
/**
* Unmapped property to handle file uploads
* #Vich\UploadableField(mapping="prototype_fichier", fileNameProperty="nomFichier")
*
* #var File $file
*/
private $file;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Projet", inversedBy="prototypes")
* #ORM\joinColumn(name="projet_id", referencedColumnName="id")
*/
private $projet;
/**
* #Assert\NotBlank()
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PrototypeHasMedia", mappedBy="prototype",cascade={"persist","remove"} )
*/
protected $links;
/**
* Remove widgetImages
*
* #param \Application\Sonata\MediaBundle\Entity\Media $widgetImages
*/
public function removeLinks(\AppBundle\Entity\PrototypeHasMedia $links)
{
$this->links->removeElement($links);
}
/**
* Get widgetImages
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getLinks()
{
return $this->links;
}
/**
* {#inheritdoc}
*/
public function setLinks($links)
{
$this->links = new ArrayCollection();
foreach ($links as $prototype) {
$this->addLinks($prototype);
}
}
/**
* {#inheritdoc}
*/
public function addLinks(\AppBundle\Entity\PrototypeHasMedia $links)
{
$links->setPrototype($this);
$this->links[] = $links;
}
public function __construct()
{
$this->dateCreation = new \DateTime("now");
$this->nom = "";
$this->description = " ";
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
public function __toString()
{
return $this->getNom();
}
/**
* Set nom
*
* #param string $nom
* #return Prototype
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Set description
*
* #param string $description
* #return Prototype
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set dateCreation
*
* #param \DateTime $dateCreation
* #return Prototype
*/
public function setDateCreation($dateCreation)
{
$this->dateCreation = $dateCreation;
return $this;
}
/**
* Get dateCreation
*
* #return \DateTime
*/
public function getDateCreation()
{
return $this->dateCreation;
}
/**
* Set projet
*
* #param \AppBundle\Entity\Projet $projet
* #return Prototype
*/
public function setProjet(\AppBundle\Entity\Projet $projet = null)
{
$this->projet = $projet;
return $this;
}
/**
* Get projet
*
* #return \AppBundle\Entity\Projet
*/
public function getProjet()
{
return $this->projet;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
*
* #param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
*/
public function setFile(File $file = null)
{
$this->file = $file;
if ($file) {
$this->updatedAt = new \DateTime('now');
}
}
/**
* #return File
*/
public function getFile()
{
return $this->file;
}
/**
* #param string $nomFichier
*/
public function setNomFichier($nomFichier)
{
$this->nomFichier = $nomFichier;
}
/**
* #return string
*/
public function getNomFichier()
{
return $this->nomFichier;
}
/**
* Set updatedAt
*
* #param \DateTime $updatedAt
* #return Prototype
*/
public function setUpdatedAt($updatedAt)
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* Get updatedAt
*
* #return \DateTime
*/
public function getUpdatedAt()
{
return $this->updatedAt;
}
/**
* Add links
*
* #param \AppBundle\Entity\PrototypeHasMedia $links
* #return Prototype
*/
public function addLink(\AppBundle\Entity\PrototypeHasMedia $links)
{
$this->links[] = $links;
return $this;
}
/**
* Remove links
*
* #param \AppBundle\Entity\PrototypeHasMedia $links
*/
public function removeLink(\AppBundle\Entity\PrototypeHasMedia $links)
{
$this->links->removeElement($links);
}
}
And in PrototypeHasMedia :
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* PrototypeHasMedia
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="AppBundle\Entity\PrototypeHasMediaRepository")
*/
class PrototypeHasMedia
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var \Application\Sonata\MediaBundle\Entity\Media
* #Assert\NotBlank()
* #ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
* #ORM\JoinColumn(name="media_id", referencedColumnName="id")
*/
protected $media;
/**
* #var \AppBundle\Entity\Prototype
* #Assert\NotBlank()
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Prototype", cascade={"persist","remove"} ,inversedBy="links", fetch="LAZY" )
* #ORM\JoinColumn(name="prototype_id", referencedColumnName="id",nullable=true)
*/
protected $prototype;
/**
* #var string
* #ORM\Column(name="link", type="text")
*/
private $link;
/**
* #var string
*
* #ORM\Column(name="commentaire", type="string", length=255)
*/
private $commentaire;
/**
* #var string
*
* #ORM\Column(name="typeDevice", type="string", length=255)
*/
private $typeDevice;
/**
* Set media
*
* #param \Application\Sonata\MediaBundle\Entity\Media $media
* #return PrototypeHasMedia
*/
public function setMedia(\Application\Sonata\MediaBundle\Entity\Media $media = null)
{
$this->media = $media;
return $this;
}
/**
* Get media
*
* #return \Application\Sonata\MediaBundle\Entity\Media
*/
public function getMedia()
{
return $this->media;
}
/**
* Set prototype
*
* #param \AppBundle\Entity\Prototype $prototype
* #return PrototypeHasMedia
*/
public function setPrototype(\AppBundle\Entity\Prototype $prototype = null)
{
$this->prototype = $prototype;
return $this;
}
/**
* Get prototype
*
* #return \AppBundle\Entity\Prototype
*/
public function getPrototype()
{
return $this->prototype;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set link
*
* #param string $link
* #return PrototypeHasMedia
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* Get link
*
* #return string
*/
public function getLink()
{
return $this->link;
}
/**
* Set commentaire
*
* #param string $commentaire
* #return Image
*/
public function setCommentaire($commentaire)
{
$this->commentaire = $commentaire;
return $this;
}
/**
* Get commentaire
*
* #return string
*/
public function getCommentaire()
{
return $this->commentaire;
}
/**
* Set typeDevice
*
* #param string $typeDevice
* #return Image
*/
public function setTypeDevice($typeDevice)
{
$this->typeDevice = $typeDevice;
return $this;
}
/**
* Get typeDevice
*
* #return string
*/
public function getTypeDevice()
{
return $this->typeDevice;
}
}
Here is prototypeAdmin.php
<?php
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class PrototypeAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('Général')
->add('nom', 'text', array('label' => 'Nom'))
->add('description','text',array('label'=>'Description'))
->add('dateCreation', 'date', array('label' => 'Date de création'))
->add('projet','entity',array('class' => 'AppBundle\Entity\Projet'))
->end()
->with('Desktop')
->add('links', 'sonata_type_collection', array(
'cascade_validation' => false,
'type_options' => array('delete' => false),
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => 'prototype'),
'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
)
)
->end()
->with('Tablette')
->add('links', 'sonata_type_collection', array(
'cascade_validation' => false,
'type_options' => array('delete' => false),
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => 'prototype'),
'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
)
)
->end()
->with('Mobile')
->add('links', 'sonata_type_collection', array(
'cascade_validation' => false,
'type_options' => array('delete' => false),
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
'link_parameters' => array('context' => 'prototype'),
'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
)
)
->end()
->with('Dossier Complet')
->add('file', 'file', array('required' => false , 'label' => 'Dossier complet'))
->end()
;
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('nom')
->add('dateCreation')
->add('projet.id')
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('nom')
->add('description')
->add('dateCreation')
->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'delete' => array(),
)
))
;
}
}
Here is PrototypeHasMediaAdmin
<?php
namespace AppBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class PrototypeHasMediaAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$link_parameters = array();
if ($this->hasParentFieldDescription()) {
$link_parameters = $this->getParentFieldDescription()->getOption('link_parameters', array());
}
if ($this->hasRequest()) {
$context = $this->getRequest()->get('context', null);
if (null !== $context) {
$link_parameters['context'] = $context;
}
}
$formMapper
->add('media', 'sonata_type_model_list', array('required' => false), array(
'link_parameters' => $link_parameters
))
->add('link', 'text', array('required' => false))
->add('commentaire', 'text', array('required' => false))
->add('typeDevice', 'text', array('required' => false))
->add('prototype','entity',array('class' => 'AppBundle\Entity\Prototype'))
;
}
}
I've tried the solution in Handling multiple file uploads in Sonata Admin Bundle but I still a problem :
I can't have the possibility to upload in many places :
I don't have the add button in the 'tablette' and 'mobile' section. I've just started using Symfony and sonata and I still feel confused.
here is what I have now :
Thank you for your help
I'm attempting to create a OneToOne Undirectional relationship between two entities. I've created the schema but when I submit the form it does not persist the data to the collection. Based off all my research I suspect it's because I don't have the owning entity set up correctly but I've tried everything I can to figure it out with no luck.
Entity - Products.php (Owning Side)
<?php
namespace SCWDesignsBundle\Entity\Products;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Mapping\ClassMetaData;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="SCWDesignsBundle\Entity\Repository\Products\ProductRespository")
* #ORM\Table(name="products")
*/
class Products {
/**
* #ORM\ID
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="ProductCategories")
* #ORM\JoinColumn(name="category_id", referencedColumnName="id")
* #Assert\NotBlank()
*/
protected $category_id;
/**
* #ORM\Column(type="boolean", options={"default" = 0})
*/
protected $featured;
/**
* #ORM\Column(type="boolean", options={"default" = 1})
*/
protected $enabled;
/**
* #ORM\Column(type="boolean", options={"default" = 0})
*/
protected $free_shipping;
/**
* #ORM\OneToOne(targetEntity="ProductSales")
* #ORM\JoinColumn(name="participate_sale", referencedColumnName="id")
*/
protected $participate_sale;
/**
* #ORM\Column(type="decimal")
*/
protected $price;
/**
* #ORM\Column(type="integer")
*/
protected $sku;
/**
* #ORM\Column(type="datetime")
*/
protected $arrival_date;
/**
* #ORM\Column(type="datetime")
*/
protected $update_date;
/*
* ArrayCollection for ProductDescription
* #ORM\OneToOne(targetEntity="ProductDescription", mappedBy="product_id", cascade={"persist"})
* #ORM\JoinColumn(name="description", referencedColumnName="product_id")
*/
protected $description;
public function __construct() {
$this->setArrivalDate(new \DateTime());
$this->description = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set featured
*
* #param boolean $featured
* #return Products
*/
public function setFeatured($featured) {
$this->featured = $featured;
return $this;
}
/**
* Get featured
*
* #return boolean
*/
public function getFeatured() {
return $this->featured;
}
/**
* Set enabled
*
* #param boolean $enabled
* #return Products
*/
public function setEnabled($enabled) {
$this->enabled = $enabled;
return $this;
}
/**
* Get enabled
*
* #return boolean
*/
public function getEnabled() {
return $this->enabled;
}
/**
* Set free_shipping
*
* #param boolean $freeShipping
* #return Products
*/
public function setFreeShipping($freeShipping) {
$this->free_shipping = $freeShipping;
return $this;
}
/**
* Get free_shipping
*
* #return boolean
*/
public function getFreeShipping() {
return $this->free_shipping;
}
/**
* Set price
*
* #param string $price
* #return Products
*/
public function setPrice($price) {
$this->price = $price;
return $this;
}
/**
* Get price
*
* #return string
*/
public function getPrice() {
return $this->price;
}
/**
* Set sku
*
* #param integer $sku
* #return Products
*/
public function setSku($sku) {
$this->sku = $sku;
return $this;
}
/**
* Get sku
*
* #return integer
*/
public function getSku() {
return $this->sku;
}
/**
* Set arrival_date
*
* #param \DateTime $arrivalDate
* #return Products
*/
public function setArrivalDate($arrivalDate) {
$this->arrival_date = $arrivalDate;
return $this;
}
/**
* Get arrival_date
*
* #return \DateTime
*/
public function getArrivalDate() {
return $this->arrival_date;
}
/**
* Set update_date
*
* #param \DateTime $updateDate
* #return Products
*/
public function setUpdateDate($updateDate) {
$this->update_date = $updateDate;
return $this;
}
/**
* Get update_date
*
* #return \DateTime
*/
public function getUpdateDate() {
return $this->update_date;
}
/**
* Set category_id
*
* #param \SCWDesignsBundle\Entity\Products\ProductCategories $categoryId
* #return Products
*/
public function setCategoryId(\SCWDesignsBundle\Entity\Products\ProductCategories $categoryId = null) {
$this->category_id = $categoryId;
return $this;
}
/**
* Get category_id
*
* #return \SCWDesignsBundle\Entity\Products\ProductCategories
*/
public function getCategoryId() {
return $this->category_id;
}
/**
* Set participate_sale
*
* #param \SCWDesignsBundle\Entity\Products\ProductSales $participateSale
* #return Products
*/
public function setParticipateSale(\SCWDesignsBundle\Entity\Products\ProductSales $participateSale = null) {
$this->participate_sale = $participateSale;
return $this;
}
/**
* Get participate_sale
*
* #return \SCWDesignsBundle\Entity\Products\ProductSales
*/
public function getParticipateSale() {
return $this->participate_sale;
}
/**
* Set description
*
* #param \SCWDesignsBundle\Entity\Products\ProductDescrition $description
* #return Products
*/
public function setDescription($description) {
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription() {
return $this->description;
}
}
Entity - ProductDescription.php
<?php
namespace SCWDesignsBundle\Entity\Products;
use Doctrine\ORM\Mapping as ORM;
use SCWDesignsBundle\Entity\BaseEntity;
use Symfony\Component\Validator\Mapping\ClassMetaData;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #ORM\Table(name="product_description")
*/
class ProductDescription extends BaseEntity {
/**
* #ORM\ManyToOne(targetEntity="Products")
* #ORM\JoinColumn(name="product_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $product_id;
/**
* #ORM\Column(type="string", columnDefinition="VARCHAR(255)")
* #Assert\Length(
* min = 2,
* max = 255,
* minMessage = "The item name must be at least {{ limit }} characters long.",
* maxMessage = "The item name cannot be longer than {{ limit }} characters."
* )
* #Assert\NotBlank()
*/
protected $name;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank()
*/
protected $brief_description;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank()
*/
protected $full_description;
/**
* #ORM\Column(type="string", columnDefinition="VARCHAR(255)")
* #Assert\Length(
* min = 2,
* max = 255,
* minMessage = "The tags characters must be at least {{ limit }} characters long.",
* maxMessage = "The tags characters cannot be longer than {{ limit }} characters."
* )
* #Assert\NotBlank()
*/
protected $meta_tags;
/**
* #ORM\Column(type="string", columnDefinition="VARCHAR(255)")
* #Assert\Length(
* min = 2,
* max = 255,
* minMessage = "The tags title must be at least {{ limit }} characters long.",
* maxMessage = "The tags title cannot be longer than {{ limit }} characters."
* )
* #Assert\NotBlank()
*/
protected $meta_title;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank()
*/
protected $meta_description;
/**
* Set name
*
* #param string $name
* #return ProductDescription
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName() {
return $this->name;
}
/**
* Set brief_description
*
* #param string $briefDescription
* #return ProductDescription
*/
public function setBriefDescription($briefDescription) {
$this->brief_description = $briefDescription;
return $this;
}
/**
* Get brief_description
*
* #return string
*/
public function getBriefDescription() {
return $this->brief_description;
}
/**
* Set full_description
*
* #param string $fullDescription
* #return ProductDescription
*/
public function setFullDescription($fullDescription) {
$this->full_description = $fullDescription;
return $this;
}
/**
* Get full_description
*
* #return string
*/
public function getFullDescription() {
return $this->full_description;
}
/**
* Set meta_tags
*
* #param string $metaTags
* #return ProductDescription
*/
public function setMetaTags($metaTags) {
$this->meta_tags = $metaTags;
return $this;
}
/**
* Get meta_tags
*
* #return string
*/
public function getMetaTags() {
return $this->meta_tags;
}
/**
* Set meta_title
*
* #param string $metaTitle
* #return ProductDescription
*/
public function setMetaTitle($metaTitle) {
$this->meta_title = $metaTitle;
return $this;
}
/**
* Get meta_title
*
* #return string
*/
public function getMetaTitle() {
return $this->meta_title;
}
/**
* Set meta_description
*
* #param string $metaDescription
* #return ProductDescription
*/
public function setMetaDescription($metaDescription) {
$this->meta_description = $metaDescription;
return $this;
}
/**
* Get meta_description
*
* #return string
*/
public function getMetaDescription() {
return $this->meta_description;
}
/**
* Get id
*
* #return integer
*/
public function getId() {
return $this->id;
}
/**
* Set product_id
*
* #param \SCWDesignsBundle\Entity\Products\Products $productId
* #return ProductDescription
*/
public function setProductId(\SCWDesignsBundle\Entity\Products\Products $productId = null) {
$this->product_id = $productId;
return $this;
}
/**
* Get product_id
*
* #return \SCWDesignsBundle\Entity\Products\Products
*/
public function getProductId() {
return $this->product_id;
}
}
FormType - NewProductFormType.php
<?php
namespace SCWDesignsBundle\Form\Admin;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use SCWDesignsBundle\Form\Types\ProductDescriptionType;
class NewProductFormType extends AbstractType {
private $entityManager;
public function __construct($entityManager) {
$this->entityManager = $entityManager;
}
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('featured', 'checkbox', array('label' => 'Featured', 'required' => false))
->add('enabled', 'checkbox', array('label' => 'Enabled', 'required' => false))
->add('freeshipping', 'checkbox', array('label' => 'Free Shipping', 'required' => false))
// ->add('participate_sale', 'checkbox', array('label' => 'Sale', 'required' => false))
->add('price', 'text', array('label' => 'Price', 'required' => true))
->add('sku', 'text', array('label' => 'Sku', 'required' => false))
->add('description', 'collection', array(
'type' => new ProductDescriptionType(),
'allow_add' => true,
'by_reference' => true
))
->add('category_id', 'entity', array(
'class' => 'SCWDesignsBundle:Products\ProductCategories',
'property' => 'name',
'placeholder' => false
));
}
public function getName() {
return 'product_new';
}
}
Type - ProductDescriptionType.php
<?php
namespace SCWDesignsBundle\Form\Types;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProductDescriptionType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('name', null, array('label' => 'Product Name', 'required' => true))
->add('full_description', 'textarea', array('label' => 'Full Description', 'required' => false))
->add('brief_description', 'textarea', array('label' => 'Brief Description', 'required' => false))
->add('meta_tags', null, array('label' => 'Meta Tags', 'required' => false))
->add('meta_title', null, array('label' => 'Meta Title', 'required' => false))
->add('meta_description', 'text', array('label' => 'Meta Description', 'required' => false));
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array('data_class' => '\SCWDesignsBundle\Entity\Products\ProductDescription'));
}
public function getName() {
return 'product_description';
}
}
Controller - ProductsController.php
public function addProductAction(Request $request) {
$categories = $this->getCategories();
$em = $this->getDoctrine()->getEntityManager();
$product = new Products();
$form = $this->createForm(new NewProductFormType($em), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$date = new \DateTime('NOW');
$product->setUpdateDate($date);
$em->persist($product);
$em->flush();
return $this->redirect($this->generateUrl('scw_designs_admin_products'));
}
return $this->render('SCWDesignsBundle:Admin\Products\Actions:new.html.twig', array(
'active_page' => 'products',
'categories' => $categories,
'form' => $form->createView(),
'action' => $this->generateUrl('scw_designs_admin_products_new')
));
}
As this caused me quite a bit of grief I've decided to post my answers after working with sshaun and ddproxy in the official #symfony irc channel.
First, I did have the owning relationship wrong. Needed to switch the inversedby to the product.php. Second I needed to presist the data, so I added the below to the controller and voila, as if magic, it worked.
if ($form->isValid()) {
$date = new \DateTime('NOW');
$product->setUpdateDate($date);
$em->persist($product);
$em->flush();
$description = $product->getDescription()->first();
$description->setProductId($product);
$em->persist($description);
$em->flush();
return $this->redirect($this->generateUrl('scw_designs_admin_products'));
}