Массив в CollectionType в формах Symfony 3.4

У меня есть массив Cart объектов, и я хочу создать общую форму, которая выглядит на экране.

введите описание изображения здесь

Как вы видите, я хочу иметь редактируемое поле Количество в каждой строке, которое представляет сущность Корзина, и я хочу иметь возможность обновлять их все сразу.

class Cart
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="carts")
*/
private $userId;

/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="carts")
*/
protected $product;

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

/*gettes & setters */
}

На данный момент у меня есть форма, которая хочет получить CollectionType, чтобы работать с ней, но — у меня есть только массив сущностей, поэтому он сбрасывает LogicalException.

Что мне нужно сделать — есть какой-нибудь способ для анализа массива в CollectionType, или, может быть, я мог бы взять группу объектов корзины из базы данных другим способом ?:

$carts=$this->getDoctrine()->getRepository(Cart::class)->findByUserId($user);

0

Решение

Существует пример того, как сделать то, что вы хотите достичь в Документация Symfony о том, как встроить коллекцию форм.

Для вашего конкретного случая использования вы захотите создать UserCartsForm и отдельный CartsForm,

В вашем UserCart добавить carts поле как CollectionType,
Затем Symfony обработает поле как последовательность форм.

SRC / AppBundle / Форма / UserCart.php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;

class UserCartsForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('carts', FormType\CollectionType::class, [
'label' => false,
'entry_type' => CartsForm::class,
'entry_options' => array('label' => false),
]);
}

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

Добавьте поля, которые вы хотите редактировать в вашей форме, в CartsForm

SRC / AppBundle / Форма / CartsForm.php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormType;

class CartsForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('quantity', FormType\IntegerType::class, [
'label' => false
//...
]);
//...
}

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

В вашем контроллере, ссылка на пользовательский объект как ваш UserCartsForm данные.

SRC / AppBundle / Controller / DefaultController.php

namespace AppBundle\Controller;

use AppBundle\Form\UserCartsForm;

class DefaultController extends Controller
{

/**
* @Route('/{id}/user-carts')
*/
public function userCartsAction(Request $request, User $user)
{
$form = $this->createForm(UserCartsForm::class, $user);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
//... process entity
//$this->getDoctrine()->getManager()->flush($carts);
return $this->redirectToRoute('some_route');
}

return $this->render('user_carts_form.html.twig', [
'form' => $form
]);
}
}

Тогда вы сможете легко извлекать данные из шаблона веточки для рендеринга так, как вам хотелось бы.

Приложение / Ресурсы / просмотров / user_carts_form.html.twig

{% form_start(form) %}
<table>
<thead>
<tr>
<td>Name</td>
<td>Quantity</td>
<td></td>
</tr>
</thead>
<tbody>
{% for cart in form.carts %}
{% set cartEntity = cart.vars.data %}
<tr>
<td>{{ cartEntity.product.name }}</td>
<td>{{ form_widget(cart.quantity) }}</td>
<td><a class="button" href="{{ path('remove_cart_action', { id: cartEntity.id }) }}">Delete <icon/></a></td>
<tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Submit</button>
{% form_end(form) %}

Обновление для ограничений сущностей

По умолчанию Symfony будет использовать все ограничения (Default) присваивается субъекту при проверке формы, вызывающей $form->isValid() вернуть ложь.

https://symfony.com/doc/3.4/validation/groups.html

Если группы не указаны, все ограничения, принадлежащие группе
Default будет применяться.

Чтобы решить проблему, используйте Группы проверки отделить ограничения сущности и объявить желаемые группы в их соответствующих формах.

Пример:

SRC / AppBundle / Entity / User.php

namespace AppBundle\Entity;

use Symfony\Component\Validator\Constraints as Assert;

/**
* @ORM\Entity
*/
class User
{

/**
* @Assert\NotBlank(groups={"registration"})
*/
private $username;

//...
}

Тогда к используйте ваши группы проверки в желаемой форме, в этом случае RegistrationForm, вы объявляете нужную группу в AbstractTye::configureOptions как один из OptionsResolver:$defaults,

SRC / AppBundle / Форма / RegistrationForm.php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;

class RegistrationForm extends AbstractType
{
//...

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

}

Теперь User::NotBlank ограничение будет применяться только для RegistrationForm::isValid() или любая другая форма, которая объявляет группу проверки регистрации.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector