YokaiManyToManyMatrixBundle
This bundle aims to render Doctrine ManyToMany relations as a matrix in a Symfony form., (*1)
Installation
Add the bundle as dependency with Composer
``` bash
composer require yokai/many-to-many-matrix-bundle, (*2)
### Enable the bundle
``` php
<?php
// config/bundles.php
return [
// ...
Yokai\ManyToManyMatrixBundle\YokaiManyToManyMatrixBundle::class => ['all' => true],
];
Usage
Let's take an example : our application is handling Symfony's security with 2 Doctrine entity : User
and Role
.
There is a ManyToMany between Role
and User
., (*3)
<?php
namespace App\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'user')]
class User
{
#[ORM\Column(type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue]
private ?int $id = null;
#[ORM\Column(type: 'string', unique: true)]
private string $email;
/**
* @var Collection<Role>
*/
#[ORM\ManyToMany(targetEntity: Role::class, inversedBy: 'users')]
private Collection $roles;
public function __toString(): string
{
return $this->email;
}
//...
}
<?php
namespace App\Entity;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'role')]
class Role
{
#[ORM\Column(type: 'integer')]
#[ORM\Id]
#[ORM\GeneratedValue]
private ?int $id = null;
#[ORM\Column(type: 'string', unique: true)]
private string $role;
/**
* @var Collection<User>
*/
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'roles')]
private Collection $users;
public function __toString(): string
{
return $this->role;
}
//...
}
I want to create a form matrix that will display the relation of these entities., (*4)
<?php
namespace App\Controller;
use App\Entity\Role;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Yokai\ManyToManyMatrixBundle\Form\Type\ManyToManyMatrixType;
class MatrixController extends AbstractController
{
#[Route(path: '/role-matrix', name: 'role-matrix')]
public function roleMatrixAction(Request $request, EntityManagerInterface $manager): Response
{
$roles = $manager->getRepository(Role::class)->findAll();
$form = $this->createForm(
ManyToManyMatrixType::class,
$roles,
[
'class' => Role::class,
'association' => 'users',
]
);
$form->handleRequest($request);
if (!$form->isSubmitted() || !$form->isValid()) {
return $this->render('role-matrix.html.twig', [
'form' => $form->createView(),
]);
}
foreach ($roles as $role) {
$manager->persist($role);
}
$manager->flush();
return $this->redirectToRoute('role-matrix');
}
}
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(form) }}
{{ form_widget(form) }}
<button type="submit" class="btn btn-primary">update matrix</button>
{{ form_end(form) }}
{% endblock %}
, (*5)
Important Notes
In the example above, we must note several IMPORTANT things., (*6)
Owning side
You MUST work with the owning side
of your association (i.e. the entity that has the ĂŹnversedBy
attribute on its ManyToMany property), (*7)
__toString
The two entities MUST have a __toString
method to render the label, (*8)
MIT License
License can be found here., (*9)
Authors
The bundle was originally created by Yann Eugoné.
See the list of contributors., (*10)