2017-06-02 1 views
1

J'essaye de créer un formulaire avec le produit sur Sylius. Un produit a un attribut 'produits' (c'est une collection de produit). Donc, dans mon formulaire, j'utilise CollectionType mais seul le dernier élément est enregistré dans la base de données.Formulaire de collection Symfony seulement dernier élément enregistré

product.php

/** 
* @ORM\Entity 
* @ORM\Table(name="sylius_product") 
*/ 
class Product extends BaseProduct 
{ 
    /** 
    * @ORM\OneToMany(targetEntity="XXX\PackBundle\Entity\PackItem", mappedBy="parent", cascade={"persist"}) 
    * @var PackItem[]|ArrayCollection $products 
    */ 
    private $products; 

    /** 
    * @ORM\Column(type="integer", nullable=true) 
    */ 
    private $area; 

    /** 
    * @ORM\Column(type="integer") 
    */ 
    private $lifetime; 

    public function __construct($lifetime=1) 
    { 
     parent::__construct(); 
     $this->products = new ArrayCollection(); 
     $this->lifetime = $lifetime; 
    } 
    /** 
    * @return PackItem[]|ArrayCollection 
    */ 
    public function getProducts() { 
     return $this->products; 
    } 

    /** 
    * @param PackItem $product 
    */ 
    public function addProduct(PackItem $product) { 
     $product->setParent($this); 
     $this->products->add($product); 
     return $this; 
    } 

    /** 
    * @param ArrayCollection|PackItem[] $products 
    */ 
    public function setProducts($products) 
    { 
     $this->products = $products; 
    } 


    /** 
    * @return True if the product is a pack 
    */ 
    public function isPack() { 
     return !($this->products->isEmpty()); 
    } 
} 

PackItem.php

/** 
* @ORM\Entity 
* @ORM\Table(name="pack_product") 
*/ 
class PackItem 
{ 
    /** 
    * @ORM\Id 
    * @ORM\ManyToOne(targetEntity="XXXX\PackBundle\Entity\Product") 
    * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    private $parent; 

    /** 
    * @ORM\Id 
    * @ORM\ManyToOne(targetEntity="XXXX\PackBundle\Entity\Product") 
    * @ORM\JoinColumn(name="child_id", referencedColumnName="id", onDelete="CASCADE") 
    */ 
    private $child; 

    /** 
    * @ORM\Column(name="quantity", type="integer") 
    */ 
    private $quantity; 

    /** 
    * @return Product 
    */ 
    public function getParent() 
    { 
     return $this->parent; 
    } 

    /** 
    * @param Product $parent 
    */ 
    public function setParent($parent) 
    { 
     $this->parent = $parent; 
     return $this; 
    } 

    /** 
    * @return Product 
    */ 
    public function getChild() 
    { 
     return $this->child; 
    } 

    /** 
    * @param Product $child 
    */ 
    public function setChild($child) 
    { 
     $this->child = $child; 
     return $this; 
    } 

    /** 
    * @return int 
    */ 
    public function getQuantity() 
    { 
     return $this->quantity; 
    } 

    /** 
    * @param int $quantity 
    */ 
    public function setQuantity($quantity) 
    { 
     $this->quantity = $quantity; 
    } 
} 

ProductTypeExtension.php

final class ProductTypeExtension extends AbstractTypeExtension 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     /** @var PackItem $packItem */ 
     $packItem = new PackItem(); 
     $packItem->setParent($builder->getData()); 
     $builder 
      ->add('products', CollectionType::class, [ 
       'entry_type' => PackItemType::class, 
       'allow_add' => true, 
       'allow_delete' => true, 
       'entry_options' => [ 
        'data' => $packItem 
       ], 
       'by_reference' => false, 
      ]); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getExtendedType() 
    { 
     return ProductType::class; 
    } 
} 

PackItemType.php

#PackItemType.php 
final class PackItemType extends AbstractType 
{ 
    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('child', 'entity', [ 
       'label' => 'XXXX.ui.token', 
       'class' => Product::class, 
       'query_builder' => function(EntityRepository $er) { 
        $qr = $er->createQueryBuilder('t') 
         ->leftJoin('t.products', 'p') 
         ->having('COUNT(p.parent) = 0') 
         ->groupBy('t.id') 
         ->orderBy('t.code', 'ASC') 
        ; 
        return $qr; 
       } 
      ]) 

      ->add('quantity', IntegerType::class) 
     ; 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => PackItem::class 
     ]); 
    } 
} 

Je sais qu'un autre sujet est à ce sujet, mais la solution ne fonctionne pas pour moi.

Merci pour votre temps.

Répondre

0

Ce code a résolu mon problème:

final class PackItemType extends AbstractType 
{ 

    /** 
    * {@inheritdoc} 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $newPack = new PackItem(); 
     $newPack->setParent($builder->getData()->getParent()); 
     $builder->setData($newPack); 
     $builder 
      ->add('child', 'entity', [ 
       'label' => 'XXXX.ui.token', 
       'class' => Product::class, 
       'query_builder' => function(EntityRepository $er) { 
        $qr = $er->createQueryBuilder('t') 
         ->leftJoin('t.products', 'p') 
         ->having('COUNT(p.parent) = 0') 
         ->groupBy('t.id') 
         ->orderBy('t.code', 'ASC') 
        ; 
        return $qr; 
       } 
      ]) 

      ->add('quantity', IntegerType::class) 
     ; 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => PackItem::class, 
     ]); 
    } 
}