Symfony 4: JSON в форму коллекции - PullRequest
0 голосов
/ 16 марта 2020

Я работаю над FormType, который будет заполнен через JSON (FOSRestBundle). У этой формы есть CollectionType, и у меня entry_type установлен другой FormType.

Но что бы я ни пытался, я получаю сообщение об ошибке: Эта форма не должна содержать дополнительных полей.

ProductCollection:

class ProductCollection
{
    const GROUP_PRODUCT_COLLECTION_LIST = "product_collection_list";

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=128)
     */
    private $name;

    /**
     * @ORM\OneToMany(targetEntity="GamePoint\Shop\Domain\ShopPackage\ShopPackage", mappedBy="productCollection")
     */
    private $shopPackages;

    /**
     * @ORM\OneToMany(targetEntity="GamePoint\Shop\Domain\ProductProductCollection\ProductProductCollection", mappedBy="productCollection")
     */
    private $productProductCollections;

ProductCollectionType:

class ProductCollectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class)
            ->add('productProductCollections', CollectionType::class, [
                'entry_type' => ProductProductCollectionType::class
            ])
        ;
    }

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

ProductProductCollection:

class ProductProductCollection
{
    /**
     * @ORM\Column(type="json")
     */
    private $settings = [];

    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="GamePoint\Shop\Domain\Product\Product", inversedBy="productProductCollections")
     */
    private $product;

    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="GamePoint\Shop\Domain\ProductCollection\ProductCollection", inversedBy="productProductCollections")
     */
    private $productCollection;

ProductProductCollectionType:

class ProductProductCollectionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('settings')
            ->add('product', EntityType::class, ['required' => false, 'class' => Product::class])
            ->add('productCollection', EntityType::class, ['required' => false, 'class' => ProductCollection::class])
        ;
    }

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

JSON отправить в маршрут:

{
    "product_collection": {
        "name": "cheap stuff",
        "productProductCollections": [
            {
                "product": 1,
                "settings" : "['test' => '123']"
            },
            {
                "product": 2,
                "settings" : "['test' => '123']"
            }
        ]
    }
}

Пакет параметров:

+request: ParameterBag {#537
    #parameters: array:1 [
      "product_collection" => array:2 [
        "name" => "cheap stuff"
        "productProductCollections" => array:2 [
          0 => array:2 [
            "product" => 1
            "settings" => "['test' => '123']"
          ]
          1 => array:2 [
            "product" => 2
            "settings" => "['test' => '123']"
          ]
        ]
      ]
    ]
  }

Всякий раз, когда я отправляю это JSON в ProductCollectionType, я получаю следующий FormErrorIterator:

array (size=1)
  0 => 
    object(Symfony\Component\Form\FormError)[613]
      protected 'messageTemplate' => string 'This form should not contain extra fields.' (length=42)
      protected 'messageParameters' => 
        array (size=1)
          '{{ extra_fields }}' => string '"0", "1"' (length=8)
      protected 'messagePluralization' => null
      private 'message' => string 'This form should not contain extra fields.' (length=42)

Там написано, что массив с ключами ProductProductCollections там - это "дополнительные поля"

Кто-нибудь знает, как должен выглядеть JSON, чтобы исправить эту ошибку?

Если попытался повторить настройте и проверьте, как Twig отправляет данные в форму, которая выглядит следующим образом:

Symfony\Component\HttpFoundation\Request {#7 ▼
  +attributes: Symfony\Component\HttpFoundation\ParameterBag {#10 ▶}
  +request: Symfony\Component\HttpFoundation\ParameterBag {#8 ▼
    #parameters: array:1 [▼
      "product_collection" => array:4 [▼
        "name" => "ewerew"
        "productSelections" => array:2 [▼
          0 => array:2 [▼
            "settings" => "qrew"
            "product" => "2"
          ]
          1 => array:2 [▼
            "settings" => "qwre"
            "product" => "1"
          ]
        ]
        "save" => ""
        "_token" => "z3um5Wu_iTZvr2OYsaGZJvtLBHVfJN5HYkO4UFQbpiw"
      ]
    ]
  }

Сохраняется нормально в настройке Twig, поэтому я действительно не вижу, что я делаю неправильно. ...

Так что я хотел бы знать, ollowing вещи:

  • Как должен JSON выглядеть, чтобы не получить эту ошибку?
  • Нужно ли что-то изменить?

1 Ответ

1 голос
/ 17 марта 2020

Попробуйте добавить атрибут allow_add к CollectionType в форме, так как по умолчанию он имеет значение false. Документация

->add('productProductCollections', CollectionType::class, [
    'entry_type' => ProductProductCollectionType::class,
    'allow_add' => true,
])

Вы также можете установить allow_extra_fields в значение по умолчанию в вашей форме. Но вы не должны использовать это, поскольку это позволяет все дополнительные поля.

$resolver->setDefaults([
    'data_class' => ProductCollection::class,
    'csrf_protection' => false,
    'allow_extra_fields' => true,
]);
...