Merge pull request #14 in WFCC/cc34 from 12-apprentiInscription to master
* commit '6121abb241cde3b7b22216a1315d9e5f583f4568': Ajout inscription et désinscription Ajout role apprenti Ajout relation élève atelier pour inscription
This commit is contained in:
commit
d3cf5f32dd
|
@ -79,3 +79,10 @@ Pas de commandes, juste du code dans AtelierController
|
||||||
|
|
||||||
### Question 10 et 11
|
### Question 10 et 11
|
||||||
Pas de commandes.
|
Pas de commandes.
|
||||||
|
|
||||||
|
### Question 12
|
||||||
|
```bash
|
||||||
|
symfony console make:entity
|
||||||
|
symfony console make:migration
|
||||||
|
symfony console d:m:m
|
||||||
|
```
|
|
@ -11,6 +11,7 @@ security:
|
||||||
property: email
|
property: email
|
||||||
role_hierarchy:
|
role_hierarchy:
|
||||||
ROLE_INSTRUCTOR: ROLE_USER
|
ROLE_INSTRUCTOR: ROLE_USER
|
||||||
|
ROLE_APPRENTI: ROLE_USER
|
||||||
firewalls:
|
firewalls:
|
||||||
dev:
|
dev:
|
||||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20230209092109 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE user_atelier (user_id INTEGER NOT NULL, atelier_id INTEGER NOT NULL, PRIMARY KEY(user_id, atelier_id), CONSTRAINT FK_B9B60629A76ED395 FOREIGN KEY (user_id) REFERENCES user (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE, CONSTRAINT FK_B9B6062982E2CF35 FOREIGN KEY (atelier_id) REFERENCES atelier (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_B9B60629A76ED395 ON user_atelier (user_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_B9B6062982E2CF35 ON user_atelier (atelier_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE user_atelier');
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use App\Entity\Atelier;
|
||||||
use App\Form\AtelierType;
|
use App\Form\AtelierType;
|
||||||
use App\Repository\AtelierRepository;
|
use App\Repository\AtelierRepository;
|
||||||
use App\Services\MarkdownAtelier;
|
use App\Services\MarkdownAtelier;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
@ -59,6 +60,7 @@ class AtelierController extends AbstractController
|
||||||
{
|
{
|
||||||
return $this->render('atelier/show.html.twig', [
|
return $this->render('atelier/show.html.twig', [
|
||||||
'atelier' => $markdownAtelier->parse($atelier),
|
'atelier' => $markdownAtelier->parse($atelier),
|
||||||
|
'inscrit' => $atelier->getEleves()->contains($this->getUser()),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,4 +101,23 @@ class AtelierController extends AbstractController
|
||||||
|
|
||||||
return $this->redirectToRoute('app_atelier_index', [], Response::HTTP_SEE_OTHER);
|
return $this->redirectToRoute('app_atelier_index', [], Response::HTTP_SEE_OTHER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[IsGranted('ROLE_APPRENTI')]
|
||||||
|
#[Route('/{id}/inscrire', name: 'app_atelier_inscription', methods: ['POST'])]
|
||||||
|
public function inscription(Request $request, Atelier $atelier, ManagerRegistry $doctrine): Response
|
||||||
|
{
|
||||||
|
$entityManager = $doctrine->getManager();
|
||||||
|
$atelier->addEleve($this->getUser());
|
||||||
|
$entityManager->flush();
|
||||||
|
return $this->redirectToRoute('app_atelier_show', ["id"=>$atelier->getId()], Response::HTTP_SEE_OTHER);
|
||||||
|
}
|
||||||
|
#[IsGranted('ROLE_APPRENTI')]
|
||||||
|
#[Route('/{id}/desinscrire', name: 'app_atelier_desinscrire', methods: ['POST'])]
|
||||||
|
public function desinscrire(Request $request, Atelier $atelier, ManagerRegistry $doctrine): Response
|
||||||
|
{
|
||||||
|
$entityManager = $doctrine->getManager();
|
||||||
|
$atelier->removeEleve($this->getUser());
|
||||||
|
$entityManager->flush();
|
||||||
|
return $this->redirectToRoute('app_atelier_show', ["id"=>$atelier->getId()], Response::HTTP_SEE_OTHER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use App\Repository\AtelierRepository;
|
use App\Repository\AtelierRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: AtelierRepository::class)]
|
#[ORM\Entity(repositoryClass: AtelierRepository::class)]
|
||||||
|
@ -19,10 +21,18 @@ class Atelier
|
||||||
#[ORM\Column(length: 1024, nullable: true)]
|
#[ORM\Column(length: 1024, nullable: true)]
|
||||||
private ?string $description = null;
|
private ?string $description = null;
|
||||||
|
|
||||||
#[ORM\ManyToOne(inversedBy: 'ateliersFormÃÃÃes')]
|
#[ORM\ManyToOne(inversedBy: 'ateliersForm<EFBFBD><EFBFBD><EFBFBD>es')]
|
||||||
#[ORM\JoinColumn(nullable: false)]
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
private ?User $instructeur = null;
|
private ?User $instructeur = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToMany(targetEntity: User::class, mappedBy: 'formationsSuivies')]
|
||||||
|
private Collection $eleves;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->eleves = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
|
@ -63,4 +73,31 @@ class Atelier
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, User>
|
||||||
|
*/
|
||||||
|
public function getEleves(): Collection
|
||||||
|
{
|
||||||
|
return $this->eleves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addEleve(User $eleve): self
|
||||||
|
{
|
||||||
|
if (!$this->eleves->contains($eleve)) {
|
||||||
|
$this->eleves->add($eleve);
|
||||||
|
$eleve->addFormationsSuivie($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeEleve(User $eleve): self
|
||||||
|
{
|
||||||
|
if ($this->eleves->removeElement($eleve)) {
|
||||||
|
$eleve->removeFormationsSuivie($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,11 +38,15 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
private ?string $prenom = null;
|
private ?string $prenom = null;
|
||||||
|
|
||||||
#[ORM\OneToMany(mappedBy: 'instructeur', targetEntity: Atelier::class, orphanRemoval: true)]
|
#[ORM\OneToMany(mappedBy: 'instructeur', targetEntity: Atelier::class, orphanRemoval: true)]
|
||||||
private Collection $ateliersFormÃÃÃes;
|
private Collection $ateliersForm<72><6D><EFBFBD>es;
|
||||||
|
|
||||||
|
#[ORM\ManyToMany(targetEntity: atelier::class, inversedBy: 'eleves')]
|
||||||
|
private Collection $formationsSuivies;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->ateliersFormÃÃÃes = new ArrayCollection();
|
$this->ateliersForm<EFBFBD><EFBFBD><EFBFBD>es = new ArrayCollection();
|
||||||
|
$this->formationsSuivies = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
|
@ -81,6 +85,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
// guarantee every user at least has ROLE_USER
|
// guarantee every user at least has ROLE_USER
|
||||||
$roles[] = 'ROLE_USER';
|
$roles[] = 'ROLE_USER';
|
||||||
$roles[] = 'ROLE_INSTRUCTOR';
|
$roles[] = 'ROLE_INSTRUCTOR';
|
||||||
|
$roles[] = 'ROLE_APPRENTI';
|
||||||
|
|
||||||
return array_unique($roles);
|
return array_unique($roles);
|
||||||
}
|
}
|
||||||
|
@ -143,15 +148,15 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
/**
|
/**
|
||||||
* @return Collection<int, Atelier>
|
* @return Collection<int, Atelier>
|
||||||
*/
|
*/
|
||||||
public function getAteliersFormÃÃÃes(): Collection
|
public function getAteliersForm<EFBFBD><EFBFBD><EFBFBD>es(): Collection
|
||||||
{
|
{
|
||||||
return $this->ateliersFormÃÃÃes;
|
return $this->ateliersForm<EFBFBD><EFBFBD><EFBFBD>es;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addAteliersFormE(Atelier $ateliersFormE): self
|
public function addAteliersFormE(Atelier $ateliersFormE): self
|
||||||
{
|
{
|
||||||
if (!$this->ateliersFormÃÃÃes->contains($ateliersFormE)) {
|
if (!$this->ateliersForm<EFBFBD><EFBFBD><EFBFBD>es->contains($ateliersFormE)) {
|
||||||
$this->ateliersFormÃÃÃes->add($ateliersFormE);
|
$this->ateliersForm<EFBFBD><EFBFBD><EFBFBD>es->add($ateliersFormE);
|
||||||
$ateliersFormE->setInstructeur($this);
|
$ateliersFormE->setInstructeur($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +165,7 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
|
|
||||||
public function removeAteliersFormE(Atelier $ateliersFormE): self
|
public function removeAteliersFormE(Atelier $ateliersFormE): self
|
||||||
{
|
{
|
||||||
if ($this->ateliersFormÃÃÃes->removeElement($ateliersFormE)) {
|
if ($this->ateliersForm<EFBFBD><EFBFBD><EFBFBD>es->removeElement($ateliersFormE)) {
|
||||||
// set the owning side to null (unless already changed)
|
// set the owning side to null (unless already changed)
|
||||||
if ($ateliersFormE->getInstructeur() === $this) {
|
if ($ateliersFormE->getInstructeur() === $this) {
|
||||||
$ateliersFormE->setInstructeur(null);
|
$ateliersFormE->setInstructeur(null);
|
||||||
|
@ -169,4 +174,28 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, atelier>
|
||||||
|
*/
|
||||||
|
public function getFormationsSuivies(): Collection
|
||||||
|
{
|
||||||
|
return $this->formationsSuivies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addFormationsSuivie(atelier $formationsSuivie): self
|
||||||
|
{
|
||||||
|
if (!$this->formationsSuivies->contains($formationsSuivie)) {
|
||||||
|
$this->formationsSuivies->add($formationsSuivie);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeFormationsSuivie(atelier $formationsSuivie): self
|
||||||
|
{
|
||||||
|
$this->formationsSuivies->removeElement($formationsSuivie);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,28 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Email instructeur</th>
|
<th>Email instructeur</th>
|
||||||
<td>{{ atelier.instructeur.email}}</td>
|
<td>{{ atelier.instructeur.email }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div class="d-flex flex-row">
|
<div class="d-flex flex-row">
|
||||||
{% if app.user and app.user == atelier.instructeur %}
|
{% if app.user and app.user == atelier.instructeur %}
|
||||||
<a class="btn btn-outline-primary m-2" href="{{ path('app_atelier_edit', {'id': atelier.id}) }}">Modifier</a>
|
<a class="btn btn-outline-primary m-2"
|
||||||
|
href="{{ path('app_atelier_edit', {'id': atelier.id}) }}">Modifier</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="btn btn-outline-primary m-2" href="{{ path('app_atelier_index') }}">Retour à la liste</a>
|
<a class="btn btn-outline-primary m-2" href="{{ path('app_atelier_index') }}">Retour à la liste</a>
|
||||||
{% if app.user and app.user == atelier.instructeur %}
|
{% if app.user and app.user == atelier.instructeur %}
|
||||||
{{ include('atelier/_delete_form.html.twig') }}
|
{{ include('atelier/_delete_form.html.twig') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if not inscrit %}
|
||||||
|
<form method="post" action="{{ path('app_atelier_inscription', {'id': atelier.id}) }}">
|
||||||
|
<button class="btn btn-outline-success m-2">S'inscrire</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<form method="post" action="{{ path('app_atelier_desinscrire', {'id': atelier.id}) }}">
|
||||||
|
<button class="btn btn-outline-danger m-2">Se désinscrire</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue