<?php
|
|
|
|
namespace App\EventSubscriber;
|
|
|
|
use App\Entity\Comment;
|
|
use App\Entity\Task;
|
|
use App\Service\OpenStreetMapClient;
|
|
use Doctrine\ORM\EntityManagerInterface;
|
|
use Symfony\Bundle\SecurityBundle\Security;
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
use Symfony\Component\Workflow\Event\EnteredEvent;
|
|
use Symfony\Component\Workflow\Event\Event;
|
|
use Symfony\Component\Workflow\Event\GuardEvent;
|
|
use Symfony\Component\Workflow\Event\TransitionEvent;
|
|
use Symfony\Component\Workflow\WorkflowInterface;
|
|
use Twig\Environment;
|
|
|
|
// Surveille la vie des tâches et réalise automatiquement des actions selon les
|
|
// circonstances
|
|
class TaskLifecycleSubscriber implements EventSubscriberInterface
|
|
{
|
|
|
|
public function __construct(
|
|
protected EntityManagerInterface $entityManager,
|
|
protected Environment $twig,
|
|
protected OpenStreetMapClient $osmClient,
|
|
protected Security $security,
|
|
protected WorkflowInterface $taskLifecycleStateMachine,
|
|
) {
|
|
}
|
|
|
|
// Cas où la tâche change d’état
|
|
public function onTransition(Event $event): void
|
|
{
|
|
$transition = $event->getTransition();
|
|
$task = $event->getSubject();
|
|
|
|
// Gère le verrouillage de la tâche
|
|
|
|
$shouldLock = $this->taskLifecycleStateMachine->getMetadataStore()->getTransitionMetadata($transition)['lock'];
|
|
$shouldUnlock = $this->taskLifecycleStateMachine->getMetadataStore()->getTransitionMetadata($transition)['unlock'];
|
|
|
|
if ($shouldLock) {
|
|
$task->lock($this->security->getUser());
|
|
} elseif ($shouldUnlock) {
|
|
$task->unlock();
|
|
}
|
|
|
|
// Commentaire automatique
|
|
$user = $this->security->getUser();
|
|
$task = $event->getSubject();
|
|
$comment = new Comment();
|
|
$comment->setTask($task);
|
|
$comment->setCreatedBy($user);
|
|
$comment->setContent($this->twig->render(sprintf('comment/%s.md.twig', $transition->getName()), [
|
|
'user' => $user,
|
|
'task' => $task,
|
|
]));
|
|
$this->entityManager->persist($comment);
|
|
$this->entityManager->flush();
|
|
}
|
|
|
|
// Bloque certaines transitions
|
|
public function onGuard(Event $event): void
|
|
{
|
|
$transition = $event->getTransition();
|
|
$task = $event->getSubject();
|
|
|
|
$shouldLock = $this->taskLifecycleStateMachine->getMetadataStore()->getTransitionMetadata($transition)['lock'];
|
|
$shouldUnlock = $this->taskLifecycleStateMachine->getMetadataStore()->getTransitionMetadata($transition)['unlock'];
|
|
|
|
$subject = $event->getSubject();
|
|
|
|
if ($shouldLock and $task->isLocked()) {
|
|
$event->setBlocked(true, 'La tâche est déjà verrouillée.');
|
|
} elseif ($shouldUnlock and !$task->isLocked()) {
|
|
$event->setBlocked(true, 'La tâche n’est pas déjà verrouillée.');
|
|
}
|
|
|
|
$event->setBlocked(false);
|
|
}
|
|
|
|
// Cas où on commence une tâche
|
|
public function onStart(Event $event): void
|
|
{
|
|
$task = $event->getSubject();
|
|
|
|
$task->setStartAt(new \DateTimeImmutable('now'));
|
|
}
|
|
|
|
// Cas où on termine une tâche
|
|
public function onFinish(Event $event): void
|
|
{
|
|
$task = $event->getSubject();
|
|
|
|
$task->setFinishAt(new \DateTimeImmutable('now'));
|
|
}
|
|
|
|
// Cas où une tâche est terminée
|
|
public function onDone(Event $event): void
|
|
{
|
|
$task = $event->getSubject();
|
|
$user = $this->security->getUser();
|
|
|
|
$task->setDoneBy($user);
|
|
|
|
// Essaie de trouver les changesets correspondants à la tâche
|
|
$task->setChangesetsResult(
|
|
json_encode($this->osmClient->getChangesets(
|
|
// On part du principe que les changesets correspondants sont
|
|
// ceux de l’utilisateur entre le moment où la tâche a été
|
|
// commencée et celui où elle a été terminée
|
|
// TODO C’est pas très précis, on doit pouvoir faire mieux
|
|
// (hashatg avec un id spécifique à l’app dans le commentaire
|
|
// du changeset, c’est moche mais ça marcherait)
|
|
$user->getUsername(),
|
|
$task->getStartAt(),
|
|
$task->getFinishAt()
|
|
))
|
|
);
|
|
}
|
|
|
|
public static function getSubscribedEvents(): array
|
|
{
|
|
return [
|
|
TransitionEvent::getName('task_lifecycle', null) => 'onTransition',
|
|
GuardEvent::getName('task_lifecycle', null) => 'onGuard',
|
|
TransitionEvent::getName('task_lifecycle', Task::TRANSITION_START) => 'onStart',
|
|
TransitionEvent::getName('task_lifecycle', Task::TRANSITION_FINISH) => 'onFinish',
|
|
EnteredEvent::getName('task_lifecycle', Task::STATUS_DONE) => 'onDone',
|
|
];
|
|
}
|
|
|
|
}
|