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

prev next

Commentaires

Connectez-vous pour laisser un commentaire