diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index 848ed0b..4706dec 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -102,6 +102,26 @@ class ProjectController extends AbstractController ]); } + #[Route('/admin/project/moveto/{id}/{status}', name: 'app_admin_project_move')] + #[Route('/user/project/moveto/{id}/{status}', name: 'app_user_project_move')] + public function move(int $id, string $status, Request $request, ProjectRepository $projectRepository, EntityManagerInterface $em): Response + { + $project = $projectRepository->find($id); + if (!$project) { + throw new NotFoundHttpException('La ressource demandée est introuvable.'); + } + + $attribute = constant(ProjectVoter::class.'::MOVE'.$status); + $this->denyAccessUnlessGranted($attribute, $project); + + $project->setStatus(constant(Project::class.'::'.$status)); + $em->flush(); + + $isAdmin = str_starts_with($request->attributes->get('_route'), 'app_admin'); + + return $this->redirectToRoute($isAdmin ? 'app_admin_project' : 'app_home'); + } + #[Route('/admin/project/delete/{id}', name: 'app_admin_project_delete')] #[Route('/user/project/delete/{id}', name: 'app_user_project_delete')] public function delete(int $id, Request $request, ProjectRepository $projectRepository, EntityManagerInterface $em): Response @@ -127,4 +147,23 @@ class ProjectController extends AbstractController return $this->redirectToRoute($isAdmin ? 'app_admin_project' : 'app_home'); } + + #[Route('/user/project/view/{id}', name: 'app_user_project_view')] + public function view(int $id, Request $request, ProjectRepository $projectRepository, EntityManagerInterface $em): Response + { + $project = $projectRepository->find($id); + if (!$project) { + throw new NotFoundHttpException('La ressource demandée est introuvable.'); + } + + $this->denyAccessUnlessGranted(ProjectVoter::VIEW, $project); + + return $this->render('project/view.html.twig', [ + 'usemenu' => true, + 'usesidebar' => false, + 'title' => 'Projet = '.$project->getTitle(), + 'routecancel' => 'app_home', + 'project' => $project, + ]); + } } diff --git a/src/Entity/Project.php b/src/Entity/Project.php index 07ae03d..91a55d7 100644 --- a/src/Entity/Project.php +++ b/src/Entity/Project.php @@ -15,7 +15,6 @@ class Project public const TOVOTE = 'A Voter'; public const VOTED = 'Voté'; public const ARCHIVED = 'Archivé'; - public const NATURE_COLLECTIVE = 'Collective'; public const NATURE_STRATEGIC = 'Stratégique'; public const NATURE_TACTICAL = 'Tactique'; diff --git a/src/Security/ProjectVoter.php b/src/Security/ProjectVoter.php index 1b32d90..6662982 100644 --- a/src/Security/ProjectVoter.php +++ b/src/Security/ProjectVoter.php @@ -15,10 +15,11 @@ class ProjectVoter extends Voter public const UPDATE = 'UPDATE'; public const DELETE = 'DELETE'; public const MOVEDRAFT = 'MOVEDRAFT'; + public const MOVETOVOTE = 'MOVETOVOTE'; protected function supports(string $attribute, $subject): bool { - $attributes = [self::VIEW, self::SUBMIT, self::UPDATE, self::DELETE, self::MOVEDRAFT]; + $attributes = [self::VIEW, self::SUBMIT, self::UPDATE, self::DELETE, self::MOVEDRAFT, self::MOVETOVOTE]; return in_array($attribute, $attributes) && $subject instanceof Project; } @@ -48,6 +49,11 @@ class ProjectVoter extends Voter return $user->hasRole('ROLE_ADMIN') || (Project::TOVOTE === $project->getStatus() && $project->getUsers()->contains($user)); } + private function canMoveToVote(Project $project, User $user): bool + { + return $user->hasRole('ROLE_ADMIN') || (Project::DRAFT === $project->getStatus() && $project->getUsers()->contains($user)); + } + protected function voteOnAttribute(string $attribute, $project, TokenInterface $token): bool { $user = $token->getUser(); @@ -61,6 +67,7 @@ class ProjectVoter extends Voter self::UPDATE => $this->canUpdate($project, $user), self::DELETE => $this->canDelete($project, $user), self::MOVEDRAFT => $this->canMoveDraft($project, $user), + self::MOVETOVOTE => $this->canMoveToVote($project, $user), default => false, }; } diff --git a/templates/home/home.html.twig b/templates/home/home.html.twig index 7abcf85..ed94fe4 100644 --- a/templates/home/home.html.twig +++ b/templates/home/home.html.twig @@ -9,6 +9,7 @@ {% if is_granted('VIEW', project) %}
+ {{project.status}}
{{project.title}}
@@ -16,7 +17,7 @@ {% endif %} - +
diff --git a/templates/project/edit.html.twig b/templates/project/edit.html.twig index c356873..7b420e0 100644 --- a/templates/project/edit.html.twig +++ b/templates/project/edit.html.twig @@ -10,6 +10,12 @@ {{ form_widget(form.submit) }} Annuler {%if mode=="update" %} + {% if is_granted('MOVEDRAFT', project) %} + Mettre en Brouillon + {% endif %} + {% if is_granted('MOVETOVOTE', project) %} + Mettre au Vote + {% endif %} {% if is_granted('DELETE', project) %} Supprimer {% endif %} diff --git a/templates/project/view.html.twig b/templates/project/view.html.twig new file mode 100644 index 0000000..6c87042 --- /dev/null +++ b/templates/project/view.html.twig @@ -0,0 +1,52 @@ +{% extends 'base.html.twig' %} + +{% block title %} = {{title}}{% endblock %} + +{% block body %} +

{{title}}

+ + + Annuler + + {% if is_granted('MOVEDRAFT', project) %} + Mettre en Brouillon + {% endif %} + {% if is_granted('MOVETOVOTE', project) %} + Mettre au Vote + {% endif %} + {% if is_granted('DELETE', project) %} + Supprimer + {% endif %} + +
+
+
+
Information
+
+ {{ project.title }} + {{ project.nature }} + {{ project.summary }} +
+
+ + {{ render(path("bninefiles_files",{domain:'project',id:project.id, editable:0})) }} + +
+
Timeline
+
+ {% include('project/timeline.html.twig') %} +
+
+
+ +
+
+
Description du Projet
+
+ {{ project.description }} +
+
+
+
+{% endblock %} +