FabRiviere / Livre_Or_Symfony

Développement du projet concernant un livre d'or sur les conférences. Projet du livre Symfony 6.
0 stars 0 forks source link

Prendre des décisions avec un workflow #39

Closed FabRiviere closed 1 year ago

FabRiviere commented 1 year ago
FabRiviere commented 1 year ago

Création d'un workflow :

symfony composer req workflow

Description du workflow sur les commentaires :

framework:
    workflows: 
        comment:
            type: state_machine
            audit_trail:
                enabled: "%kernel.debug%"
            marking_store:
                type: 'method'
                property: 'state'
            supports:
                - App\Entity\Comment
            initial_marking: submitted
            places:
                - submitted
                - ham
                - potential_spam
                - spam
                - rejected
                - published
            transitions:
                accept:
                    from: submitted
                    to: ham
                might_be_spam:
                    from: submitted
                    to: potential_spam
                reject_spam:
                    from: submitted
                    to: spam
                publish:
                    from: potential_spam
                    to: published
                reject:
                    from: potential_spam
                    to: rejected
                publish_ham:
                    from: ham
                    to: published
                reject_ham:
                    from: ham
                    to: rejected

Génération de la représentation visuelle du workflow pour validation.

Installation de l'utilitaire Graphviz :

Graphviz

Générer la représentation :

symfony console workflow:dump comment | dot -Tpng -o workflow.png

Utilisation du workflow

Modification du CommentMessageHandler.php :

public function __invoke(CommentMessage $message)
    {
        $comment = $this->commentRepository->find($message->getId());
        if (!$comment) {
            return;
        }

        // ! Mis en commentaire pour utilisation du WorkflowInterface
        // if (2 === $this->spamChecker->getSpamScore($comment, $message->getContext())) {
        //     $comment->setState('spam');
        // } else {
        //     $comment->setState('published');
        // }

        // $this->entityManager->flush();

        //! Utilisation du Workflow
        if ($this->commentStateMachine->can($comment, 'accept')) {
            $score = $this->spamChecker->getSpamScore($comment, $message->getContext());
            $transition = match ($score) {
                2 => 'reject_spam',
                1 => 'might_be_spam',
                default => 'accept',
            };
            $this->commentStateMachine->apply($comment, $transition);
            $this->entityManager->flush();
            $this->bus->dispatch($message);
        } elseif ($this->commentStateMachine->can($comment, 'publish') || $this->commentStateMachine->can($comment, 'publish_ham')) {
            $this->commentStateMachine->apply($comment, $this->commentStateMachine->can($comment, 'publish') ? 'publish' : 'publish_ham');
        }elseif ($this->logger) {
            $this->logger->debug('Dropping comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);
        }
    }

La nouvelle logique se lit comme ceci :

Si la transition accept est disponible pour le commentaire dans le message, vérifiez si c'est un spam ; Selon le résultat, choisissez la bonne transition à appliquer ; Appellez apply() pour mettre à jour le Comment via un appel à la méthode setState() ; Appelez flush() pour valider les changements dans la base de données ; Réexpédiez le message pour permettre au workflow d'effectuer une nouvelle transition. Comme nous n'avons pas implémenté la fonctionnalité de validation par l'admin, la prochaine fois que le message sera consommé, le message "Dropping comment message" sera enregistré.

Nous mettons en place la validation automatique (pour l'instant) dans la première condition elseif.