You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

239 lines
8.7 KiB

<?php
namespace App\Controller;
use App\Entity\Comment;
use App\Entity\Project;
use App\Entity\Task;
use App\Form\CsvType;
use App\Form\ProjectType;
use App\Service\OverpassClient;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
#[Route('/project')]
class ProjectController extends AbstractController
{
// Page des projets, où l'on voit tous les projets
#[Route('/', name: 'app_project')]
public function index(EntityManagerInterface $entityManager): Response
{
$projects = $entityManager->getRepository(Project::class)->findAllOrderedByActivity();
return $this->render('project/index.html.twig', [
'projects' => $projects,
]);
}
// Formulaire de création d’un projet
#[Route('/create', name: 'app_project_create')]
public function create(Request $request, EntityManagerInterface $entityManager): Response
{
$project = new Project();
$createForm = $this->createForm(ProjectType::class, $project);
$createForm->add('submit', SubmitType::class, [
'label' => 'Créer',
]);
$createForm->handleRequest($request);
if ($createForm->isSubmitted() and $createForm->isValid()) {
$project = $createForm->getData();
try {
$project->setCreatedBy($this->getUser());
$entityManager->persist($project);
$entityManager->flush();
$this->addFlash('success', 'Projet créé !');
return $this->redirectToRoute('app_project');
} catch (\Exception $exception) {
$this->addFlash('danger', 'Impossible de créer le projet !');
}
}
return $this->render('project/create.html.twig', [
'create_form' => $createForm,
]);
}
// Page d’un prtojet donné (où l’on voit ses tâches)
#[Route('/{slug}', name: 'app_project_show')]
public function show(EntityManagerInterface $entityManager, $slug): Response
{
$project = $entityManager->getRepository(Project::class)->findOneBySlug($slug);
if (!$project) {
$this->addFlash('warning', 'Projet non trouvé !');
return $this->redirectToRoute('app_project');
}
$tasks = $entityManager->getRepository(Task::class)->findByProjectPaginated($project);
$randomTask = $entityManager->getRepository(Task::class)->findRandomByProject($project, Task::STATUS_TODO); // Trouve la tâche à faire que l’on piochera
$csvForm = $this->createForm(CsvType::class, null, [
'action' => $this->generateUrl('app_project_import', ['slug' => $slug]),
]);
$csvForm->add('submit', SubmitType::class, ['label' => 'Importer']);
$comments = $entityManager->getRepository(Comment::class)->findLatestByProject($project); // Commentaires agrégés de toutes les tâches du projet
return $this->render('project/show.html.twig', [
'project' => $project,
'tasks' => $tasks,
'csv_form' => $csvForm,
'comments' => $comments,
'randomTask' => $randomTask,
]);
}
// Import de tâches dans un projet
#[Route('/{slug}/import', name: 'app_project_import')]
public function import(Request $request, EntityManagerInterface $entityManager, $slug): Response
{
$project = $entityManager->getRepository(Project::class)->findOneBySlug($slug);
if (!$project) {
$this->addFlash('warning', 'Projet non trouvé !');
return $this->redirectToRoute('app_project');
}
$csvForm = $this->createForm(CsvType::class, null, [
'allow_extra_fields' => true,
]);
$csvForm->handleRequest($request);
if ($csvForm->isSubmitted() and $csvForm->isValid()) {
$csvFile = $csvForm->get('csv')->getData();
// TODO un peu plus de gestion d’erreur ici serait pas du luxe…
$csv = fopen($csvFile->getPathName(), 'r');
$col = array_flip(fgetcsv($csv));
while ($row = fgetcsv($csv)) {
$task = new Task();
$task->setCreatedBy($this->getUser());
$task->setProject($project);
$task->setName($row[$col['name']]);
$task->setDescription($row[$col['description']]);
$task->setOsm($row[$col['osm']]);
$task->setGeojson($row[$col['geojson']]);
if (isset($row[$col['status']]) and in_array($row[$col['status']], [
Task::STATUS_TODO,
Task::STATUS_DOING,
Task::STATUS_DONE,
])) {
$task->setStatus($row[$col['status']]);
} else {
$task->setStatus(Task::STATUS_TODO);
}
$entityManager->persist($task);
}
$entityManager->flush();
}
return $this->redirectToRoute('app_project_show', ['slug' => $slug]);
}
// Page de modification du projet
#[Route('/{slug}/update', name: 'app_project_update')]
public function update(Request $request, EntityManagerInterface $entityManager, $slug): Response
{
$repository = $entityManager->getRepository(Project::class);
$project = $repository->findOneBySlug($slug);
if (!$project) {
$this->addFlash('warning', 'Projet non trouvé !');
return $this->redirectToRoute('app_project');
}
$updateForm = $this->createForm(ProjectType::class, $project);
$updateForm->add('submit', SubmitType::class, [
'label' => 'Modifier',
]);
$updateForm->handleRequest($request);
if ($updateForm->isSubmitted() and $updateForm->isValid()) {
$project = $updateForm->getData();
try {
$entityManager->persist($project);
$entityManager->flush();
$this->addFlash('success', 'Projet modifié !');
return $this->redirectToRoute('app_project_show', ['slug' => $slug]);
} catch (\Exception $exception) {
$this->addFlash('danger', 'Impossible de mopdifier le projet !');
}
}
return $this->render('project/update.html.twig', [
'project' => $project,
'update_form' => $updateForm,
]);
}
// La suppression d’un projet passe par là
#[Route('/{slug}/remove', name: 'app_project_remove')]
public function remove(EntityManagerInterface $entityManager, $slug): Response
{
$repository = $entityManager->getRepository(Project::class);
$project = $repository->findOneBySlug($slug);
if (!$project) {
$this->addFlash('warning', 'Projet non trouvé !');
return $this->redirectToRoute('app_project');
}
try {
$entityManager->remove($project);
$entityManager->flush();
return $this->redirectToRoute('app_project');
} catch (\Exception $exception) {
$this->addFlash('danger', 'Impossible de supprimer le projet !');
}
return $this->redirectToRoute('app_project');
}
// Effectue la requête Overpass liée au projet
#[Route('/{slug}/overpass', name: 'app_project_overpass')]
public function overpass(OverpassClient $overpassClient, EntityManagerInterface $entityManager, $slug): Response
{
$repository = $entityManager->getRepository(Project::class);
$project = $repository->findOneBySlug($slug);
if (!$project) {
$this->addFlash('warning', 'Projet non trouvé !');
return $this->redirectToRoute('app_project');
}
if (!$project->hasOverpassQuery()) {
$this->addFlash('warning', 'Ce projet n’a pas de requête Overpass !');
return $this->redirectToRoute('app_project_show', ['slug' => $project->getSlug()]);
}
if ($project->hasOverpassResult() and !$project->isOverpassResultOutdated()) {
$this->addFlash('warning', 'Merci d’attendre un peu avant de requêter de nouveau Overpass !');
return $this->redirectToRoute('app_project_show', ['slug' => $project->getSlug()]);
}
$result = $overpassClient->query($project->getOverpassQuery());
$project->setOverpassResult($result);
$entityManager->persist($project);
$entityManager->flush();
return $this->redirectToRoute('app_project_show', ['slug' => $project->getSlug()]);
}
}