Gérer les participants
Écrire sur participants
On va autoriser uniquement l'auteur de la Discussion à écrire sur participants
. Pour ça dans notre entitié Discussion on va rajouter la condition object.getAuthor() === user
sur put
. Ainsi on regarde si l'auteur de notre object (en l'occurrence Discussion) correspond à l'utilisateur identifié (user) et si oui on peut écrire.
On rajoute également le groupe de denormalization
:
* itemOperations={
* "get",
* "put"={
* "security"="object.getAuthor() === user"
* }
* },
* normalizationContext={"groups"={"discussion:read"}},
* denormalizationContext={"groups"={"discussion:write"}},
* subresourceOperations={},
* accessControl="is_granted('ROLE_USER')"
* )
* @ORM\Entity(repositoryClass=DiscussionRepository::class)
*/
class Discussion
On rajoute également le groupe sur l'attribut participants
/**
* @ORM\ManyToMany(targetEntity=User::class)
* @Groups({"discussion:read", "discussion:write"})
*/
private $participants;
Se retirer de la Discussion
L'auteur peut ajouter ou supprimer des participants. Nous allons créer une route pour un utilisateur qui n'est pas auteur mais qui souhaite quitter la Discussion.
On déclare notre nouvelle route dans Discussion
* itemOperations={
* "get",
* "put"={
* "security"="object.getAuthor() === user"
* },
* "quitDiscussion"={
* "method"="DELETE",
* "path"="discussions/{id}/quit-discussion"
* }
* },
Et on va créer le DataPersister qui va gérer notre logique
<?php
// src/DataPersister/QuitDiscussionDataPersister.php
namespace App\DataPersister;
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
use App\Entity\Discussion;
use Symfony\Component\Security\Core\Security;
class QuitDiscussionDataPersister implements ContextAwareDataPersisterInterface
{
private $decorated;
private $security;
public function __construct(ContextAwareDataPersisterInterface $decorated, Security $security){
$this->decorated = $decorated;
$this->security = $security;
}
public function supports($data, array $context = []): bool
{
return $data instanceof Discussion
&& (array_key_exists('item_operation_name', $context)
&& $context['item_operation_name'] === 'quitDiscussion');
}
public function persist($data, array $context = [])
{
}
/**
* @param Discussion $data
* @param array $context
* @return void
*/
public function remove($data, array $context = [])
{
$user = $this->security->getUser();
$data->removeParticipant($user);
$this->decorated->persist($data);
}
}
On vérifie qu'on est bien sur l'opération quitDiscussion
qui est le nom de la route et comme nous utilisons le verbe DELETE c'est la méthode remove
qui est appelée. Dans cette méthode on récupère l'utilisateur actuellement connecté et on l'envoie en paramètre de removeParticipant
pour pouvoir le retirer.
On oublie pas de décorer notre persister dans services.yaml
App\DataPersister\QuitDiscussionDataPersister:
bind:
$decorated: '@api_platform.doctrine.orm.data_persister'
Et voilà, maintenant si vous êtes dans les participants de la Discussion 1 et que vous voulez vous retirer il suffit de faire DELETE api/discussions/1/quit-discussion
Commentaires
Connectez-vous pour laisser un commentaire