收集形式Symfony只保存最后一项

时间:2017-06-02 07:46:45

标签: php symfony collections product sylius

我正在尝试在Sylius上创建一个带有产品的表单。产品具有属性'产品'(它是产品的集合)。因此,在我的表单中,我使用CollectionType,但只有最后一项保存在数据库中。

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
        ]);
    }
}

我知道另一个主题就是这个,但解决方案对我不起作用。

感谢您的时间。

1 个答案:

答案 0 :(得分:0)

这段代码解决了我的问题:

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,
        ]);
    }
}