Обработка самоссылающихся сложных структур данных с помощью Symfony Forms - PullRequest
0 голосов
/ 19 февраля 2019

Как обработать следующую структуру данных через формы Symfony?

Сущность, которая содержит коллекцию сущности, которая имеет отношение к себе:

Order
    /** @var OrderProduct */
    $orderProducts

    public function getQuoteProducts()
    {
        return $this->quoteProducts;
    }

    public function addOrderProduct(OrderProduct $orderProduct)
    {
        if (!$this->orderProducts->contains($orderProduct)) {
            $this->orderProducts[] = $orderProduct;
            $orderProduct->setOrder($this);
        }

        return $this;
    }

    public function removeOrderProduct(OrderProduct $orderProduct)
    {
        if ($this->orderProducts->contains($orderProduct)) {
            $this->orderProducts->removeElement($orderProduct);
        }

        return $this;
    }

OrderProduct
    /** @var Order */
    $order
    /** @var OrderProduct */
    $relatedOrderProducts

    public function addRelatedOrderProduct(OrderProduct $orderProduct)
    {
        if (!$this->relatedOrderProducts->contains($orderProduct)) {
            $this->relatedOrderProducts[] = $orderProduct;
            $orderProduct->setMainOrderProduct($this);
        }

        return $this;
    }

    public function removeRelatedOrderProduct(OrderProduct $orderProduct)
    {
        if ($this->relatedOrderProducts->contains($orderProduct)) {
            $this->relatedOrderProducts->removeElement($orderProduct);
            $orderProduct->setMainOrderProduct(null);
        }

        return $this;
    }

Запрос:

'order' => [
    'some_order_property' => 'value',
    // ...
    'orderProducts' => [
        'some_order_product_property' => 'value',
        // ...
        'relatedOrderProducts' => [
            [
                'some_order_product_property' => 'value',
                // ...
            ],
            [
                'some_order_product_property' => 'value',
                // ...
            ],
        ]
    ]
]

Формы:

OrderType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('orderProducts', OrderProductCollectionType::class)
            ->add(...);
    }

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

OrderProductCollectionType

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'type'         => OrderProductType::NAME,
            'allow_add'    => true,
            'allow_delete' => true,
            'by_reference' => false,
            'prototype'    => true,
        ]);
    }

OrderProductType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('relatedOrderProducts', RelatedOrderProductCollectionType::class)
            ->add(...);
    }

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

RelatedOrderProductCollectionType

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'type'         => RelatedOrderProductType::NAME,
            'allow_add'    => true,
            'allow_delete' => true,
            'by_reference' => false,
            'prototype'    => true,
        ]);
    }

RelatedOrderProductType

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add(...);
    }

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

Эта настройка работает, только она не связана OrderProducts с RelatedOrderProductType формы с Order (поэтому для order_id установлено значение null).Когда это отношение принудительно (например, с помощью прослушивателя FormEvent), то все отношения удаляются при последующей отправке формы.Скорее всего, это связано с тем, что для сущности установлено значение orphanRemoval=true.

Возможно, в моем примере отсутствуют некоторые детали, но у меня общий вопрос: может ли эта структура данных обрабатываться с помощью форм Symfony?Если так, то как?

...