Давайте представим, что мы хотим назначить категории для публикации, мы используем EntityType для их генерации на основе количества категорий, которые у нас есть, поэтому мы просто добавляем следующий блок кода в нашу форму:
Контроллер:
->add('categories', EntityType::class, array(
'class' => Category::class,
'choice_label' => 'category_description',
'multiple' => true,
'expanded' => true,
'required' => false,
))
А затем сохраните их в базе данных при отправке формы, ManyToMany, используя ArrayCollection:
foreach($post_data['categories'] as $form_category)
{
$database_category = $database_manager->getRepository(Category::class)->find($form_category->getId());
$post->addCategory($database_category);
}
Юридическое лицо:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass = "App\Repository\PostRepository")
*/
class Post
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type = "integer")
*/
private $id;
...
/**
* @ORM\ManyToMany(targetEntity = "Category", cascade = {"persist"})
* @ORM\JoinTable(name = "junction_table",
* joinColumns = {@ORM\JoinColumn(name = "post_id", referencedColumnName = "id")},
* inverseJoinColumns = {@ORM\JoinColumn(name = "category_id", referencedColumnName = "id")}
* )
*/
private $categories;
public function __construct() {
$this->categories = new ArrayCollection();
}
...
public function getCategories()
{
return $this->categories;
}
public function addCategory(Category $category): self
{
$this->categories->add($category);
return $this;
}
}
Изображение:
Сгенерированные чекбоксы с описанием и индексом
Но что, если я хочу, чтобы эти флажки были предварительно выбраны, когда я перехожу в режим редактирования, чтобы пользователь знал, какие из них были выбраны в прошлый раз, как вы подойдете к этому?
Также как бы вы удалили один, если он не выбран?
@Nek, да, он возвращает коллекцию, я опубликовал объект, чтобы вы могли его увидеть.
Можете ли вы добавить контроллер к вашему вопросу?
@DJava Я имел в виду, возвращает ли он коллекцию с ожидаемыми элементами внутри. Возможно, предоставление нам своего шаблона поможет нам




Если поля вашей формы сопоставлены с сущностью, данные должны быть установлены автоматически. Вам даже не нужно вручную добавлять категории в сообщение.
Вот полный образец рабочего кода, который соответствует тому, что вы хотите сделать:
//src/Entity/Group.php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass = "App\Repository\GroupRepository")
* @ORM\Table(name = "`group`")
*/
class Group
{
/**
* Group constructor.
*/
public function __construct()
{
$this->players = new ArrayCollection();
}
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @ORM\ManyToMany(targetEntity = "App\Entity\Player", inversedBy = "groups")
*/
private $players;
/**
* @return mixed
*/
public function getPlayers()
{
return $this->players;
}
/**
* @param mixed $players
*
* @return Group
*/
public function setPlayers($players)
{
$this->players = $players;
return $this;
}
/**
* @param Player $player
*
* @return Group
*/
public function addPlayer(Player $player)
{
$this->players->add($player);
return $this;
}
/**
* @param Player $player
*
* @return Group
*/
public function removePlayer(Player $player)
{
$this->players->removeElement($player);
return $this;
}
}
//src/Entity/Player.php
namespace App\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass = "App\Repository\PlayerRepository")
*/
class Player
{
/**
* @return string
*/
public function __toString()
{
return $this->name;
}
/**
* Player constructor.
*/
public function __construct()
{
$this->groups = new ArrayCollection();
}
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type = "integer")
*/
private $id;
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @ORM\ManyToMany(targetEntity = "App\Entity\Group", mappedBy = "players")
*/
private $groups;
/**
* @return mixed
*/
public function getGroups()
{
return $this->groups;
}
/**
* @param mixed $groups
*
* @return Player
*/
public function setGroups($groups)
{
$this->groups = $groups;
return $this;
}
/**
* @param Group $group
*
* @return Player
*/
public function addGroup(Group $group)
{
$this->groups->add($group);
return $this;
}
/**
* @param Group $group
*
* @return Player
*/
public function removeGroup(Group $group)
{
$this->groups->removeElement($group);
return $this;
}
}
//src/Form/GroupType.php
namespace App\Form;
use App\Entity\Group;
use App\Entity\Player;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class GroupType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'players',
EntityType::class,
[
'class' => Player::class,
'multiple' => true,
'expanded' => true,
'required' => false,
]
);
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => Group::class,
]
);
}
}
//src/Controller/GroupController.php
namespace App\Controller;
use App\Entity\Group;
use App\Form\GroupType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class GroupController extends Controller
{
/**
* @Route("/edit-group/{id}", name = "group_edit")
* @param Request $request
* @param Group $group
*
* @return Response
*/
public function editGroup(Request $request, Group $group)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(GroupType::class, $group);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($group);
$em->flush();
}
return new Response(
$this->renderView(
'group/edit-group.html.twig',
array(
'form' => $form->createView(),
)
)
);
}
}
//templates/group/edit-group.html.twig
{% extends 'base.html.twig' %}
{% block body %}
<div class = "container">
<div class = "row">
<h1>Edit group</h1>
</div>
{{ form_start(form) }}
{{ form_row(form.players) }}
<button type = "submit" class = "btn btn-success">Edit</button>
{{ form_rest(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
Он выдает: / dm-config / dashboard / add-post - Допустимый размер памяти 134217728 байт исчерпан (попытался выделить 262144 байта) в / Users / aeca / Documents / SymfonyProjects / cms / vendor / doctrine / или / m / lib / Doctrine / ORM / P ersistentCollection. php on line 480
Хорошо, мне удалось заставить его работать, добавив 'data' => $ post-> getCategories () в мой EntityType, так что это решило это, но я все еще борюсь, когда флажок не установлен, поэтому категория удаляется из сообщения.
Так должно быть проще. Я обновлю свой ответ, чтобы поставить рабочий код, чтобы вы могли сравнить.
Большое вам спасибо, да, это в значительной степени то, что я искал.
Symfony автоматически заполняет флажки, когда у вас уже есть данные внутри вашей сущности, даже если они не сохраняются. Вы уверены, что $ post-> getCategories () вернет ожидаемую коллекцию? Для отмены выбора та же история: Symfony Form Component сделает это за вас.