I has 2 tables, Subproduto and Subpedido, subpedido has many subproduto. First I try make attribute $subprodutos type json_array, but the entitytype returned {} array empty. Then I still try relationship, but without success.
Subproduto.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Subproduto
*
* #ORM\Table(name="subproduto")
* #ORM\Entity(repositoryClass="AppBundle\Repository\SubprodutoRepository")
*/
class Subproduto
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="descricao", type="string", length=50)
*/
private $descricao;
/**
* #var string
*
* #ORM\Column(name="valor", type="decimal", scale=2)
*/
private $valor;
/**
* #var int
*
* #ORM\Column(name="multiplo", type="smallint")
*/
private $multiplo=1;
/**
* #var int
*
* #ORM\Column(name="ativo", type="smallint")
*/
private $ativo=1;
/**
* #ORM\ManyToOne(targetEntity="Subcategoria", inversedBy="subprodutos")
* #ORM\JoinColumn(name="subcategoria_id", referencedColumnName="id")
*/
protected $subcategoria;
/**
* #ORM\ManyToOne(targetEntity="Estoque", inversedBy="subprodutos")
* #ORM\JoinColumn(name="estoque_id", referencedColumnName="id")
*/
protected $estoque;
/**
* #ORM\OneToMany(targetEntity="Subpedido", mappedBy="subproduto")
*/
private $subpedidos;
/**
* #return string
*/
public function __toString()
{
return $this->descricao;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set descricao
*
* #param string $descricao
*
* #return Subproduto
*/
public function setDescricao($descricao)
{
$this->descricao = $descricao;
return $this;
}
/**
* Get descricao
*
* #return string
*/
public function getDescricao()
{
return $this->descricao;
}
/**
* Set valor
*
* #param string $valor
*
* #return Subproduto
*/
public function setValor($valor)
{
$this->valor = $valor;
return $this;
}
/**
* Get valor
*
* #return string
*/
public function getValor()
{
return $this->valor;
}
/**
* Set multiplo
*
* #param integer $multiplo
*
* #return Subproduto
*/
public function setMultiplo($multiplo)
{
$this->multiplo = $multiplo;
return $this;
}
/**
* Get multiplo
*
* #return integer
*/
public function getMultiplo()
{
return $this->multiplo;
}
/**
* Set ativo
*
* #param integer $ativo
*
* #return Subproduto
*/
public function setAtivo($ativo)
{
$this->ativo = $ativo;
return $this;
}
/**
* Get ativo
*
* #return integer
*/
public function getAtivo()
{
return $this->ativo;
}
/**
* Set subcategoria
*
* #param \AppBundle\Entity\Subcategoria $subcategoria
*
* #return Subproduto
*/
public function setSubcategoria(\AppBundle\Entity\Subcategoria $subcategoria = null)
{
$this->subcategoria = $subcategoria;
return $this;
}
/**
* Get subcategoria
*
* #return \AppBundle\Entity\Subcategoria
*/
public function getSubcategoria()
{
return $this->subcategoria;
}
/**
* Set estoque
*
* #param \AppBundle\Entity\Estoque $estoque
*
* #return Subproduto
*/
public function setEstoque(\AppBundle\Entity\Estoque $estoque = null)
{
$this->estoque = $estoque;
return $this;
}
/**
* Get estoque
*
* #return \AppBundle\Entity\Estoque
*/
public function getEstoque()
{
return $this->estoque;
}
/**
* Constructor
*/
public function __construct()
{
$this->subpedido = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add subpedido
*
* #param \AppBundle\Entity\Subpedido $subpedido
*
* #return Subproduto
*/
public function addSubpedido(\AppBundle\Entity\Subpedido $subpedido)
{
$this->subpedido[] = $subpedido;
return $this;
}
/**
* Remove subpedido
*
* #param \AppBundle\Entity\Subpedido $subpedido
*/
public function removeSubpedido(\AppBundle\Entity\Subpedido $subpedido)
{
$this->subpedido->removeElement($subpedido);
}
/**
* Get subpedido
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSubpedido()
{
return $this->subpedido;
}
/**
* Get subpedidos
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSubpedidos()
{
return $this->subpedidos;
}
}
Subpedido.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Subpedido
*
* #ORM\Table(name="subpedido")
* #ORM\Entity(repositoryClass="AppBundle\Repository\SubpedidoRepository")
*/
class Subpedido
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="quantidade", type="smallint")
*/
private $quantidade;
/**
* #ORM\ManyToOne(targetEntity="Subproduto", inversedBy="subpedidos", cascade={"persist"})
* #ORM\JoinColumn(name="subproduto_id", referencedColumnName="id")
*/
protected $subproduto;
/**
* #ORM\ManyToOne(targetEntity="Pedido", inversedBy="subpedidos")
* #ORM\JoinColumn(name="pedido_id", referencedColumnName="id")
*/
protected $pedido;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set quantidade
*
* #param integer $quantidade
*
* #return Subpedido
*/
public function setQuantidade($quantidade)
{
$this->quantidade = $quantidade;
return $this;
}
/**
* Get quantidade
*
* #return integer
*/
public function getQuantidade()
{
return $this->quantidade;
}
/**
* Set subproduto
*
* #param \AppBundle\Entity\Subproduto $subproduto
*
* #return Subpedido
*/
public function setSubproduto(\AppBundle\Entity\Subproduto $subproduto = null)
{
$this->subproduto = $subproduto;
return $this;
}
/**
* Get subproduto
*
* #return \AppBundle\Entity\Subproduto
*/
public function getSubproduto()
{
return $this->subproduto;
}
/**
* Set pedido
*
* #param \AppBundle\Entity\Pedido $pedido
*
* #return Subpedido
*/
public function setPedido(\AppBundle\Entity\Pedido $pedido = null)
{
$this->pedido = $pedido;
return $this;
}
/**
* Get pedido
*
* #return \AppBundle\Entity\Pedido
*/
public function getPedido()
{
return $this->pedido;
}
}
SubpedidoType.php
<?php
namespace AppBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SubpedidoType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$subcategorias = $options['subcategorias'];
$builder
->add('quantidade')
->add('subproduto',EntityType::class, array(
'class'=>'AppBundle:Subproduto',
'expanded'=>true,
'multiple'=>true,
'label'=>false,
'choice_label'=>function($subproduto){
return $subproduto->getDescricao(). ' '. $subproduto->getValor();
},
'query_builder' => function(EntityRepository $er) use ( $subcategorias ){
return $this->querySubcategorias($subcategorias, $er);
},
))
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Subpedido',
'subcategorias'=>null,
));
}
/**
* #param $subcategorias, $er
* Funcao que monta a query para filtrar as subcategorias existentes na categoria listada no pedido
*/
public function querySubcategorias($subcategorias, $er){
$query = $er->createQueryBuilder('u'); //set repository categoria
$count = 1;
//na primeira montagem eh Where as demais andWhere
foreach($subcategorias as $subcategoria){
if($count<2)
$query->where('u.subcategoria = ?'.$count)->setParameter($count,$subcategoria);
else
$query->orWhere('u.subcategoria =?'.$count)->setParameter($count,$subcategoria);
$count++;
}
return $query;
}
}
SubpedidoController.php
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Pedido;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use AppBundle\Entity\Subpedido;
use AppBundle\Form\SubpedidoType;
/**
* Subpedido controller.
*
* #Route("/subpedido")
*/
class SubpedidoController extends Controller
{
/**
* Lists all Subpedido entities.
*
* #Route("/", name="subpedido_index")
* #Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$subpedidos = $em->getRepository('AppBundle:Subpedido')->findAll();
return $this->render('subpedido/index.html.twig', array(
'subpedidos' => $subpedidos,
));
}
/**
* Creates a new Subpedido entity.
*
* #Route("/new/{categoria}/{pedido}", name="subpedido_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request, $categoria, $pedido)
{
$subpedido = new Subpedido();
$pedido = new Pedido($pedido);
$em = $this->getDoctrine()->getManager();
$subpedido->setPedido($pedido->getId());
//busca todas as subcategorias da categoria escolhida
$subcategoria = $em->getRepository('AppBundle:Subcategoria')->findBy(
array('categoria'=>$categoria, 'ativo'=>1,));
$form = $this->createForm('AppBundle\Form\SubpedidoType', $subpedido, array(
'subcategorias'=>$subcategoria,
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($subpedido);
$em->flush();
return $this->redirectToRoute('subpedido_show', array('id' => $subpedido->getId()));
}
return $this->render('subpedido/new.html.twig', array(
'subpedido' => $subpedido,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Subpedido entity.
*
* #Route("/{id}", name="subpedido_show")
* #Method("GET")
*/
public function showAction(Subpedido $subpedido)
{
$deleteForm = $this->createDeleteForm($subpedido);
return $this->render('subpedido/show.html.twig', array(
'subpedido' => $subpedido,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Subpedido entity.
*
* #Route("/{id}/edit", name="subpedido_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Subpedido $subpedido)
{
$deleteForm = $this->createDeleteForm($subpedido);
$editForm = $this->createForm('AppBundle\Form\SubpedidoType', $subpedido);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($subpedido);
$em->flush();
return $this->redirectToRoute('subpedido_edit', array('id' => $subpedido->getId()));
}
return $this->render('subpedido/edit.html.twig', array(
'subpedido' => $subpedido,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Subpedido entity.
*
* #Route("/{id}", name="subpedido_delete")
* #Method("DELETE")
*/
public function deleteAction(Request $request, Subpedido $subpedido)
{
$form = $this->createDeleteForm($subpedido);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($subpedido);
$em->flush();
}
return $this->redirectToRoute('subpedido_index');
}
/**
* Creates a form to delete a Subpedido entity.
*
* #param Subpedido $subpedido The Subpedido entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Subpedido $subpedido)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('subpedido_delete', array('id' => $subpedido->getId())))
->setMethod('DELETE')
->getForm()
;
}
}
Related
I apologize in advance for a noob question. I just started learning symfony and I ran into a roadblock.
I created the RequestForEstimate entity and it may have multiple records associated under the RequestForEstimateDetail entity. Now, Im trying to create a form that not only displays fields from the first entity but also from the second one as well. Symfony doesn't return any errors however it doesn't render the "quantity" field from the RequestForEstimateDetail entity. I used the following tutorial to create this code: How to Embed a Collection of Forms
This is an example of my RequestForEstimate entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimate
*
* #ORM\Table(name="request_for_estimate")
* #ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateRepository")
*/
class RequestForEstimate
{
/**
* #var int
*
* #ORM\Column(name="requestId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="status", type="integer")
*/
private $status;
/**
* #var \DateTime
*
* #ORM\Column(name="createTime", type="datetime")
*/
private $createTime;
/**
* #var \DateTime
*
* #ORM\Column(name="updateTime", type="datetime")
*/
private $updateTime;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="RequestForEstimateDetail", mappedBy="detail", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $details;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set status
*
* #param integer $status
*
* #return RequestForEstimate
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return int
*/
public function getStatus()
{
return $this->status;
}
/**
* Set createTime
*
* #param \DateTime $createTime
*
* #return RequestForEstimate
*/
public function setCreateTime($createTime)
{
$this->createTime = $createTime;
return $this;
}
/**
* Get createTime
*
* #return \DateTime
*/
public function getCreateTime()
{
return $this->createTime;
}
/**
* Set updateTime
*
* #param \DateTime $updateTime
*
* #return RequestForEstimate
*/
public function setUpdateTime($updateTime)
{
$this->updateTime = $updateTime;
return $this;
}
/**
* Get updateTime
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->updateTime;
}
/**
* Set name
*
* #param string $name
*
* #return RequestForEstimate
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Constructor
*/
public function __construct()
{
$this->details = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add detail
*
* #param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*
* #return RequestForEstimate
*/
public function addDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details[] = $detail;
return $this;
}
/**
* Remove detail
*
* #param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*/
public function removeDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details->removeElement($detail);
}
/**
* Get details
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDetails()
{
return $this->details;
}
}
This is my RequestForEstimateDetail entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimateDetail
*
* #ORM\Table(name="request_for_estimate_detail")
* #ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateDetailRepository")
*/
class RequestForEstimateDetail
{
/**
* #var int
*
* #ORM\Column(name="requestDetailId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="RequestForEstimate", inversedBy="details")
* #ORM\JoinColumn(name="requestId", referencedColumnName="requestId")
*/
private $detail;
/**
* #var int
*
* #ORM\Column(name="productId", type="integer")
*/
private $productId;
/**
* #var int
*
* #ORM\Column(name="quantity", type="integer")
*/
private $quantity;
/**
* #var string
*
* #ORM\Column(name="pricePerUnit", type="decimal", precision=2, scale=0)
*/
private $pricePerUnit;
/**
* #var string
*
* #ORM\Column(name="shippingCost", type="decimal", precision=2, scale=0)
*/
private $shippingCost;
/**
* #var string
*
* #ORM\Column(name="otherFees", type="decimal", precision=2, scale=0)
*/
private $otherFees;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set product
*
* #param integer $product
*
* #return RequestForEstimateDetail
*/
public function setProduct($product)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* #return int
*/
public function getProduct()
{
return $this->product;
}
/**
* Set quantity
*
* #param integer $quantity
*
* #return RequestForEstimateDetail
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* #return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Set pricePerUnit
*
* #param string $pricePerUnit
*
* #return RequestForEstimateDetail
*/
public function setPricePerUnit($pricePerUnit)
{
$this->pricePerUnit = $pricePerUnit;
return $this;
}
/**
* Get pricePerUnit
*
* #return string
*/
public function getPricePerUnit()
{
return $this->pricePerUnit;
}
/**
* Set shippingCost
*
* #param string $shippingCost
*
* #return RequestForEstimateDetail
*/
public function setShippingCost($shippingCost)
{
$this->shippingCost = $shippingCost;
return $this;
}
/**
* Get shippingCost
*
* #return string
*/
public function getShippingCost()
{
return $this->shippingCost;
}
/**
* Set otherFees
*
* #param string $otherFees
*
* #return RequestForEstimateDetail
*/
public function setOtherFees($otherFees)
{
$this->otherFees = $otherFees;
return $this;
}
/**
* Get otherFees
*
* #return string
*/
public function getOtherFees()
{
return $this->otherFees;
}
/**
* Set requestId
*
* #param \SourcingBundle\Entity\RequestForEstimate $requestId
*
* #return RequestForEstimateDetail
*/
public function setRequestId(\SourcingBundle\Entity\RequestForEstimate $requestId = null)
{
$this->requestId = $requestId;
return $this;
}
/**
* Get requestId
*
* #return \SourcingBundle\Entity\RequestForEstimate
*/
public function getRequestId()
{
return $this->requestId;
}
/**
* Set productId
*
* #param \SourcingBundle\Entity\Product $productId
*
* #return RequestForEstimateDetail
*/
public function setProductId(\SourcingBundle\Entity\Product $productId = null)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return \SourcingBundle\Entity\Product
*/
public function getProductId()
{
return $this->productId;
}
/**
* Set detail
*
* #param \SourcingBundle\Entity\RequestForEstimate $detail
*
* #return RequestForEstimateDetail
*/
public function setDetail(\SourcingBundle\Entity\RequestForEstimate $detail = null)
{
$this->detail = $detail;
return $this;
}
/**
* Get detail
*
* #return \SourcingBundle\Entity\RequestForEstimate
*/
public function getDetail()
{
return $this->detail;
}
}
This is my RequestForEstimateController:
<?php
namespace SourcingBundle\Controller;
use SourcingBundle\Entity\RequestForEstimate;
use SourcingBundle\Form\Type\RequestForEstimateType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class RequestForEstimateController extends Controller
{
/**
* #Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
These are my form classes:
RequestForEstimateType.php
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class RequestForEstimateType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('details', CollectionType::class, array(
'entry_type' => RequestForEstimateDetailType::class
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimate',
));
}
}
RequestForEstimateDetailType.php:
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RequestForEstimateDetailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('quantity',TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimateDetail',
));
}
}
Now my view:
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Create Request For Estimate</h5>
</div>
<div class="ibox-content">
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_widget(form) }}
</div>
{{ dump(form.details)}}
{% for detail in form.details %}
<li>{{ form_row(detail.quantity) }}</li>
{% endfor %}
{{ form_end(form) }}
</div>
</div>
</div>
</div>
You need to create some RequestForEstimateDetail entities in your controller class and add it to RequestForEstimate entity. Like this:
class RequestForEstimateController extends Controller
{
/**
* #Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$detail1 = new RequestForEstimateDetail();
$detail2 = new RequestForEstimateDetail();
$RequestForEstimate->addDetail($detail1);
$RequestForEstimate->addDetail($detail2);
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
PS. U can read this doc http://symfony.com/doc/current/form/form_collections.html it's pretty clear =)
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 created a one to many relationship between a society and its employees. Everything worked great, I can see the user list when I'm editing the society page and I can select some of them, but the problem is that I can't save / persist those data, and i don't know why.
I tried a lot of things, like adding allow_add =>true or by_reference => false inside the FormType, but it doesn't work even though it still saves the rest of the form, such as the society's name and its address.
Here are the entities :
Societe.php
<?php
namespace SocieteBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Societe
*
* #ORM\Table(name="societe")
* #ORM\Entity(repositoryClass="SocieteBundle\Repository\SocieteRepository")
*/
class Societe
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="RaisonSociale", type="string", length=255, unique=true)
*/
private $raisonSociale;
/**
* #var string
*
* #ORM\Column(name="adresse", type="string", length=255, unique=true)
*/
private $adresse;
/**
* #ORM\OneToMany(targetEntity="UserBundle\Entity\User", mappedBy="entreprise", cascade={"persist"})
*/
private $salaries;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set raisonSociale
*
* #param string $raisonSociale
*
* #return Societe
*/
public function setRaisonSociale($raisonSociale)
{
$this->raisonSociale = $raisonSociale;
return $this;
}
/**
* Get raisonSociale
*
* #return string
*/
public function getRaisonSociale()
{
return $this->raisonSociale;
}
/**
* Set adresse
*
* #param string $adresse
*
* #return Societe
*/
public function setAdresse($adresse)
{
$this->adresse = $adresse;
return $this;
}
/**
* Get adresse
*
* #return string
*/
public function getAdresse()
{
return $this->adresse;
}
/**
* Constructor
*/
public function __construct()
{
$this->salaries = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add salary
*
* #param \UserBundle\Entity\User $salary
*
* #return Societe
*/
public function addSalary(\UserBundle\Entity\User $salary)
{
$this->salaries[] = $salary;
return $this;
}
/**
* Remove salary
*
* #param \UserBundle\Entity\User $salary
*/
public function removeSalary(\UserBundle\Entity\User $salary)
{
$this->salaries->removeElement($salary);
}
/**
* Get salaries
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getSalaries()
{
return $this->salaries;
}
/**
* Set salaries
* Something I tried, didn't work
*/
public function setSalaries($salaries)
{
$this->salaries = $salaries;
return $this;
}
}
User.php
<?php
namespace UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
* #ORM\Column(name="prenom", type="string", length=255, nullable=true)
*/
protected $prenom;
/**
* #var string
* #ORM\Column(name="nom", type="string", length=255, nullable=true)
*/
protected $nom;
/**
* #var string
* #ORM\Column(name="telephone", type="string", length=255, nullable=true)
*/
protected $telephone;
/**
* #ORM\OneToMany(targetEntity="MissionBundle\Entity\Mission", mappedBy="createur", cascade={"remove", "persist"})
*
*/
protected $post;
/**
* #ORM\ManyToOne(targetEntity="EcoleBundle\Entity\Ecole", inversedBy="representant", cascade={"persist"})
* #ORM\JoinColumn(name="ecole_id", referencedColumnName="id")
*/
protected $ecole;
/**
* #ORM\ManyToOne(targetEntity="SocieteBundle\Entity\Societe", inversedBy="salaries", cascade={"persist"})
* #ORM\JoinColumn(name="salaries_id", referencedColumnName="id")
*/
private $entreprise;
/**
* Set prenom
*
* #param string $prenom
*
* #return User
*/
public function setPrenom($prenom)
{
$this->prenom = $prenom;
return $this;
}
/**
* Get prenom
*
* #return string
*/
public function getPrenom()
{
return $this->prenom;
}
/**
* Set nom
*
* #param string $nom
*
* #return User
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* #return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set telephone
*
* #param string $telephone
*
* #return User
*/
public function setTelephone($telephone)
{
$this->telephone = $telephone;
return $this;
}
/**
* Get telephone
*
* #return string
*/
public function getTelephone()
{
return $this->telephone;
}
/**
* Add post
*
* #param \MissionBundle\Entity\Mission $post
*
* #return User
*/
public function addPost(\MissionBundle\Entity\Mission $post)
{
$this->post[] = $post;
return $this;
}
/**
* Remove post
*
* #param \MissionBundle\Entity\Mission $post
*/
public function removePost(\MissionBundle\Entity\Mission $post)
{
$this->post->removeElement($post);
}
/**
* Get post
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getPost()
{
return $this->post;
}
/**
* Set post
*
* #param \Doctrine\Common\Collections\Collection $comments
*/
public function setDeskComment(\Doctrine\Common\Collections\Collection $post){
$this->post = $post;
}
/**
* Set ecole
*
* #param \EcoleBundle\Entity\Ecole $ecole
*
* #return User
*/
public function setEcole(\EcoleBundle\Entity\Ecole $ecole = null)
{
$this->ecole = $ecole;
return $this;
}
/**
* Get ecole
*
* #return \EcoleBundle\Entity\Ecole
*/
public function getEcole()
{
return $this->ecole;
}
/**
* Set entreprise
*
* #param \SocieteBundle\Entity\Societe $entreprise
*
* #return User
*/
public function setEntreprise(\SocieteBundle\Entity\Societe $entreprise = null)
{
$this->entreprise = $entreprise;
return $this;
}
/**
* Get entreprise
*
* #return \SocieteBundle\Entity\Societe
*/
public function getEntreprise()
{
return $this->entreprise;
}
}
SocieteType.php
<?php
namespace SocieteBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
//use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SocieteType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('raisonSociale')
->add('adresse')
->add('salaries', null, array(
'by_reference' => false,
)
)
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SocieteBundle\Entity\Societe'
));
}
}
SocieteController.php
<?php
namespace SocieteBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use SocieteBundle\Entity\Societe;
use SocieteBundle\Form\SocieteType;
/**
* Societe controller.
*
* #Route("/societe")
*/
class SocieteController extends Controller
{
/**
* Lists all Societe entities.
*
* #Route("/", name="societe_index")
* #Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$societes = $em->getRepository('SocieteBundle:Societe')->findAll();
return $this->render('societe/index.html.twig', array(
'societes' => $societes,
));
}
/**
* Creates a new Societe entity.
*
* #Route("/new", name="societe_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$societe = new Societe();
$form = $this->createForm('SocieteBundle\Form\SocieteType', $societe);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($societe);
$em->flush();
return $this->redirectToRoute('societe_show', array('id' => $societe->getId()));
}
return $this->render('societe/new.html.twig', array(
'societe' => $societe,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Societe entity.
*
* #Route("/{id}", name="societe_show")
* #Method("GET")
*/
public function showAction(Societe $societe)
{
$deleteForm = $this->createDeleteForm($societe);
return $this->render('societe/show.html.twig', array(
'societe' => $societe,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Societe entity.
*
* #Route("/{id}/edit", name="societe_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Societe $societe)
{
$deleteForm = $this->createDeleteForm($societe);
$editForm = $this->createForm('SocieteBundle\Form\SocieteType', $societe);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($societe);
$em->flush();
return $this->redirectToRoute('societe_edit', array('id' => $societe->getId()));
}
return $this->render('societe/edit.html.twig', array(
'societe' => $societe,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Societe entity.
*
* #Route("/{id}", name="societe_delete")
* #Method("DELETE")
*/
public function deleteAction(Request $request, Societe $societe)
{
$form = $this->createDeleteForm($societe);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($societe);
$em->flush();
}
return $this->redirectToRoute('societe_index');
}
/**
* Creates a form to delete a Societe entity.
*
* #param Societe $societe The Societe entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Societe $societe)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('societe_delete', array('id' => $societe->getId())))
->setMethod('DELETE')
->getForm()
;
}
}
Please tell me if you want me to add a file to the question, I'll edit it. Thank you in advance
edit: I can see the array with the user I selected if I dump the form content
In your SocieteType.php change:
->add('salaries', null, array(
'by_reference' => false,
)
to
->add('salaries', 'entity', array(
'class' => 'SocieteBundle\Entity\Societe',
'property' => 'raisonSociale',
)
I am creating a Chat system. I have two entities Chat and ChatThread.
namespace Acme\UitBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Chat
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\UitBundle\Entity\ChatRepository")
* #ORM\HasLifecycleCallbacks()
*/
class Chat
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="chats")
* #ORM\JoinColumn(name="uid", referencedColumnName="id")
*/
private $user;
/**
* #var string
*
* #ORM\Column(name="msg", type="text")
*/
private $msg;
/**
* #ORM\ManyToOne(targetEntity="ChatThread", inversedBy="chats")
* #ORM\JoinColumn(name="tid", referencedColumnName="id")
*/
private $thread;
/**
* #var \DateTime
*
* #ORM\Column(name="date", type="datetime")
*/
private $date;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user
*
* #param \stdClass $user
* #return Chat
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \stdClass
*/
public function getUser()
{
return $this->user;
}
/**
* Set msg
*
* #param string $msg
* #return Chat
*/
public function setMsg($msg)
{
$this->msg = $msg;
return $this;
}
/**
* Get msg
*
* #return string
*/
public function getMsg()
{
return $this->msg;
}
/**
* Set date
*
* #param \DateTime $date
* #return Chat
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* #return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* #ORM\PrePersist
*/
public function setDateValue()
{
$this->date = new \DateTime();
}
/**
* Set thread
*
* #param \Acme\UitBundle\Entity\ChatThread $thread
* #return Chat
*/
public function setThread(\Acme\UitBundle\Entity\ChatThread $thread = null)
{
$this->thread = $thread;
return $this;
}
/**
* Get thread
*
* #return \Acme\UitBundle\Entity\ChatThread
*/
public function getThread()
{
return $this->thread;
}
}
Entity ChatThread :
namespace Acme\UitBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\OrderBy;
use Doctrine\Common\Collections\ArrayCollection;
/**
* ChatThread
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="Acme\UitBundle\Entity\ChatThreadRepository")
*/
class ChatThread
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToMany(targetEntity="User", inversedBy="inside")
*/
private $inside;
/**
* #ORM\OneToMany(targetEntity="Chat", mappedBy="thread")
* #OrderBy({"date" = "DESC"})
*/
private $chats;
public function __construct()
{
$this->chats=new ArrayCollection();
$this->inside=new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set inside
*
* #param array $inside
* #return ChatThread
*/
public function setInside($inside)
{
$this->inside = $inside;
return $this;
}
/**
* Get inside
*
* #return array
*/
public function getInside()
{
return $this->inside;
}
/**
* Add inside
*
* #param \Acme\UitBundle\Entity\User $inside
* #return ChatThread
*/
public function addInside(\Acme\UitBundle\Entity\User $inside)
{
$this->inside[] = $inside;
return $this;
}
/**
* Remove inside
*
* #param \Acme\UitBundle\Entity\User $inside
*/
public function removeInside(\Acme\UitBundle\Entity\User $inside)
{
$this->inside->removeElement($inside);
}
/**
* Add chats
*
* #param \Acme\UitBundle\Entity\Chat $chats
* #return ChatThread
*/
public function addChat(\Acme\UitBundle\Entity\Chat $chats)
{
$this->chats[] = $chats;
return $this;
}
/**
* Remove chats
*
* #param \Acme\UitBundle\Entity\Chat $chats
*/
public function removeChat(\Acme\UitBundle\Entity\Chat $chats)
{
$this->chats->removeElement($chats);
}
/**
* Get chats
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getChats()
{
return $this->chats;
}
}
What I want to do is Take users to be added in inside and create a ChatThread and add a msg in Chat.
I have a form of chatType which takes user id's as collection with name thread. I have used a data transformer to transform inside into ChatThread.
namespace Acme\UitBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Acme\UitBundle\Form\DataTransformer\ThreadToInsideTransformer;
class ChatType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$entityManager = $options['em'];
$transformer = new ThreadToInsideTransformer($entityManager);
$builder->add(
$builder->create('thread', 'collection' ,array('allow_add' => true,'label' => false))->addModelTransformer($transformer)
);
$builder->add('msg','textarea');
/* $builder->add('inside','collection',array(
'allow_add' => true,
'allow_delete' => true)); */
$builder->add('hook', 'submit');
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'Acme\UitBundle\Entity\Chat'
))
->setRequired(array(
'em',
))
->setAllowedTypes(array(
'em' => 'Doctrine\Common\Persistence\ObjectManager',
));
}
public function getName() {
return 'chat';
}
}
data transformer
namespace Acme\UitBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
use Acme\UitBundle\Entity\ChatThread;
class ThreadToInsideTransformer implements DataTransformerInterface
{
/**
* #var ObjectManager
*/
private $om;
/**
* #param ObjectManager $om
*/
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
/**
* Transforms an object (thread) to an array (inside).
*
* #param Thread $thread
* #return array
*/
public function transform($thread)
{
if (null === $thread) {
return "";
}
return $thread->getInside();
}
/**
* Transforms a array (inside) to an object (thread).
*
* #param array $inside
*
* #return Thread
*
* #throws Create new Thread if object (thread) is not found.
*/
public function reverseTransform($inside)
{
if (!is_array($inside)) {
return null;
}
$a=$this->om
->getRepository('AcmeUitBundle:User')
->findById($inside);
if (null === $a) {
throw new TransformationFailedException(sprintf(
'Error. . .'
));
}
$thread = $this->om
->getRepository('AcmeUitBundle:ChatThread')
->findByInsideChat($a)
;
if (null === $thread) {
$thread=new ChatThread();
$thread->setInside($inside);
$this->om->persist($thread);
$this->om->flush();
}
return $thread;
}
}
When I submit form, I get this error Expected argument of type "object, array or empty", "string" given.
I have two entities Store and Category and each Store has it's own categories.
I'd like that when a Store owner's try to add a new category and category_parent, just the categories related to current Store will be displayed.
Right now, all categories are displayed in the select-option.
I'm using Tree Gedmo extension to manage Category entity and I use getChildrenQueryBuilder method to select categories.
How can I modify this method and add my specific constraint ?
$store which is the constraint is declared in the controller action down.
I'd like te set current Category option disabled when he try to add a category_parent, so category and category parent must be differnt.
I hope it's clear
CategoryType.php
<?php
namespace Project\StoreBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class CategoryType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
//..........
//..........
->add('category', 'entity', array(
'required' => false,
'label' => 'Category parent',
'class' => 'ProjectStoreBundle:Category',
'attr' => array('class' => 'col-sm-8'),
'empty_value' => 'Select one category',
'property' => 'indentedName',
'multiple' => false,
'expanded' => false ,
'query_builder' => function (\Project\StoreBundle\Entity\CategoryRepository $r)
{
return $r->getChildrenQueryBuilder(null, null, 'root', 'asc', false);
}
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Project\StoreBundle\Entity\Category'
));
}
/**
* #return string
*/
public function getName()
{
return 'project_storebundle_category';
}
}
Entity/Category.php
<?php
namespace Project\StoreBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Category
* #Gedmo\Tree(type="nested")
* #ORM\Table()
* #ORM\Entity(repositoryClass="Project\StoreBundle\Entity\CategoryRepository")
* #ORM\HasLifeCycleCallbacks()
*/
class Category
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*
*#Assert\NotBlank(message="Please enter the name of categorie.")
*/
private $name;
/**
* #Gedmo\slug(fields={"name"}, unique_base="uniqueBase")
* #ORM\Column(name="slug",length=255, unique=false)
*/
private $slug ;
/**
* #ORM\Column(name="uniqueBase", type="integer")
*/
private $uniqueBase ;
/**
* #ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* #ORM\Column(name="metaDescription", type="string", length=255, nullable=true)
*
* #Assert\Length(
* max=255,
* maxMessage="message"
* )
*/
private $metaDescription;
/**
* #ORM\Column(name="metaKeywords", type="string", length=255, nullable=true)
*
* #Assert\Length(
* max=255,
* maxMessage="message"
* )
*/
private $metaKeywords;
/**
* #ORM\Column(name="enabled", type="boolean", nullable=false)
*/
private $enabled;
/**
* #Gedmo\TreeLeft
* #ORM\Column(name="lft", type="integer")
*/
private $lft;
/**
* #Gedmo\TreeLevel
* #ORM\Column(name="lvl", type="integer")
*/
private $lvl;
/**
* #Gedmo\TreeRight
* #ORM\Column(name="rgt", type="integer")
*/
private $rgt;
/**
* #Gedmo\TreeRoot
* #ORM\Column(name="root", type="integer", nullable=true)
*/
private $root;
/**
* #Gedmo\TreeParent
* #ORM\ManyToOne(targetEntity="Category", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="Category", mappedBy="parent")
* #ORM\OrderBy({"lft" = "ASC"})
*/
private $children;
/**
*non mapped property
*/
private $indentedName;
/**
*non mapped property
*/
private $category;
/**
* #ORM\ManyToOne(targetEntity="Project\StoreBundle\Entity\Store", inversedBy="categories", cascade={"persist"})
* #ORM\JoinColumn(nullable=false)
*/
private $store ;
/**
* Constructor
*/
public function __construct()
{
$this->children = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Category
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set slug
*
* #param string $slug
* #return Category
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* #return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set uniqueBase
*
* #param integer $uniqueBase
* #return Category
*/
public function setUniqueBase($uniqueBase)
{
$this->uniqueBase = $uniqueBase;
return $this;
}
/**
* Get uniqueBase
*
* #return integer
*/
public function getUniqueBase()
{
return $this->uniqueBase;
}
/**
* Set description
*
* #param string $description
* #return Category
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set metaDescription
*
* #param string $metaDescription
* #return Category
*/
public function setMetaDescription($metaDescription)
{
$this->metaDescription = $metaDescription;
return $this;
}
/**
* Get metaDescription
*
* #return string
*/
public function getMetaDescription()
{
return $this->metaDescription;
}
/**
* Set metaKeywords
*
* #param string $metaKeywords
* #return Category
*/
public function setMetaKeywords($metaKeywords)
{
$this->metaKeywords = $metaKeywords;
return $this;
}
/**
* Get metaKeywords
*
* #return string
*/
public function getMetaKeywords()
{
return $this->metaKeywords;
}
/**
* Set enabled
*
* #param boolean $enabled
* #return Category
*/
public function setEnabled($enabled)
{
$this->enabled = $enabled;
return $this;
}
/**
* Get enabled
*
* #return boolean
*/
public function getEnabled()
{
return $this->enabled;
}
/**
* Set parent
*
* #param \Project\StoreBundle\Entity\Category $parent
* #return Category
*/
public function setParent(\Project\StoreBundle\Entity\Category $parent = null)
{
$this->parent = $parent;
return $this;
}
/**
* Get parent
*
* #return \Project\StoreBundle\Entity\Category
*/
public function getParent()
{
return $this->parent;
}
/**
* Set lft
*
* #param integer $lft
* #return Category
*/
public function setLft($lft)
{
$this->lft = $lft;
return $this;
}
/**
* Get lft
*
* #return integer
*/
public function getLft()
{
return $this->lft;
}
/**
* Set lvl
*
* #param integer $lvl
* #return Category
*/
public function setLvl($lvl)
{
$this->lvl = $lvl;
return $this;
}
/**
* Get lvl
*
* #return integer
*/
public function getLvl()
{
return $this->lvl;
}
/**
* Set rgt
*
* #param integer $rgt
* #return Category
*/
public function setRgt($rgt)
{
$this->rgt = $rgt;
return $this;
}
/**
* Get rgt
*
* #return integer
*/
public function getRgt()
{
return $this->rgt;
}
/**
* Set root
*
* #param integer $root
* #return Category
*/
public function setRoot($root)
{
$this->root = $root;
return $this;
}
/**
* Get root
*
* #return integer
*/
public function getRoot()
{
return $this->root;
}
/**
* Add children
*
* #param \Project\StoreBundle\Entity\Category $children
* #return Category
*/
public function addChild(\Project\StoreBundle\Entity\Category $children)
{
$this->children[] = $children;
return $this;
}
/**
* Remove children
*
* #param \Project\StoreBundle\Entity\Category $children
*/
public function removeChild(\Project\StoreBundle\Entity\Category $children)
{
$this->children->removeElement($children);
}
/**
* Get children
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
/**
* Get IndentedName
*
*/
public function getIndentedName()
{
return str_repeat("-----", $this->lvl).$this->name;
}
/**
* Get category
*
*/
public function getCategory()
{
return $this->category;
}
/**
* Set store
*
* #param \Project\StoreBundle\Entity\Store $store
* #return Category
*/
public function setStore(\Project\StoreBundle\Entity\Store $store = null)
{
$this->store = $store;
return $this;
}
/**
* Get store
*
* #return \Project\StoreBundle\Entity\Store
*/
public function getStore()
{
return $this->store;
}
}
Controller
/**
* Create a new Category entity.
*
*/
/**
* #ParamConverter("store", options={"mapping": {"store_id":"id"}})
*/
public function newAction(Store $store)
{
// keep in mind, this will call all registered security voters
if (false === $this->get('security.context')->isGranted('edit', $store)) {
throw new AccessDeniedException('Unauthorised access!');
}
$category = new Category();
$category->setStore($store);
$category->setUniqueBase($store->getId());
$form = $this->createForm(new CategoryType(), $category);
$request = $this->getRequest();
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->persist($category);
$em->flush();
$this->get('session')->getFlashBag()->add('message', 'Category enregistred');
return $this->redirect( $this->generateUrl('dashboard_category_index', array('store_id' => $store->getId())));
}
}
return $this->render('ProjectDashboardBundle:Category:new.html.twig',
array(
'form' => $form->createView() ,
'store' =>$store,
));
}
I managed to pass the parameter $store to the form, but I don't know how to use it as a constraint in getChildrenQueryBuilder method.
Should I create a new custom method? I prefer to use getChildrenQueryBuilder if it is possible.
Here is the new code
CategoryType.php
class CategoryType extends AbstractType
{
private $store;
public function __construct($store)
{
$this->store = $store;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$store = $this->store;
$builder
//...........
//...........
->add('parent', 'entity', array(
'required' => false,
'label' => 'Category parent',
'class' => 'ProjectStoreBundle:Category',
'attr' => array('class' => 'col-sm-8'),
'empty_value' => 'Select one category',
'property' => 'indentedName',
'multiple' => false,
'expanded' => false ,
'query_builder' => function (\Project\StoreBundle\Entity\CategoryRepository $r) use ($store)
{
return $r->getChildrenQueryBuilder(null, null, 'root', 'asc', false);
}
))
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Project\StoreBundle\Entity\Category'
));
}
/**
* #return string
*/
public function getName()
{
return 'project_storebundle_category';
}
}
Controller
/**
* #ParamConverter("store", options={"mapping": {"store_id":"id"}})
*/
public function newAction(Store $store)
{
// keep in mind, this will call all registered security voters
if (false === $this->get('security.context')->isGranted('edit', $store)) {
throw new AccessDeniedException('Unauthorised access!');
}
$category = new Category();
$category->setStore($store);
$category->setUniqueBase($store->getId());
$form = $this->createForm(new CategoryType($store), $category);
$request = $this->getRequest();
if ($request->getMethod() == 'POST')
{
$form->bind($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->persist($category);
$em->flush();
$this->get('session')->getFlashBag()->add('message', 'Category enregistred');
return $this->redirect( $this->generateUrl('dashboard_category_index', array('store_id' => $store->getId())));
}
}
return $this->render('ProjectDashboardBundle:Category:new.html.twig',
array(
'form' => $form->createView() ,
'store' =>$store,
));
}
You're not saying which Symfony2 version you're using, but generically speaking, you just need to find a way to pass the current store to your form builder and use it in the method that filters the possible categories.
Take a look at this one, or this one, basically you just need to inject the $store into your form builder, and then you (almost) have it :-)