<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Departement;
use App\Entity\Region;
use App\Entity\Structure;
use App\Entity\User;
use App\Form\SimpleStructureType;
use App\Form\StructureType;
use App\Repository\StructureRepository;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Structure controller.
*/
#[Route(path: '/structure')]
class StructureController extends AbstractController
{
private EntityManagerInterface $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* Lists all csx structure.
*/
#[Route(path: '/csx', name: 'list_csx')]
#[Route(path: '/evs', name: 'list_evs')]
#[Route(path: '/admin/cafs', name: 'list_caf')]
#[Route(path: '/admin/federations', name: 'list_fdd')]
public function listStructures(Request $request, PaginatorInterface $paginator): Response
{
$routeName = $request->get('_route');
switch ($routeName) {
case 'list_evs':
$title = 'Liste des espaces de vie sociale';
$structure_type_id = 2;
$type_structure = 'EVS';
break;
case 'list_csx':
default:
$title = 'Liste des centres sociaux';
$structure_type_id = 4;
$type_structure = 'CSO';
break;
case 'list_caf':
$title = 'Liste des CAFS';
$structure_type_id = 3;
$type_structure = 'CAF';
break;
case 'list_fdd':
$title = 'Liste des fédérations';
$structure_type_id = 5;
$type_structure = 'FDD';
break;
}
$query = $request->query;
$filter_name = $query->get('name', '');
$filter_ville = $query->get('ville', '');
$filter_departement = $query->get('departement', '');
$filter_region = $query->get('region', '');
// recuperations des départements
$departements = $this->em->getRepository(Departement::class)->getAllByRegion($filter_region);
$regions = $this->em->getRepository(Region::class)->findAll();
$pagination = $paginator->paginate(
$this->em->getRepository(Structure::class)->getListStructure(
$query->get('sort', 'e.id'),
$query->get('direction', 'ASC'),
$structure_type_id,
$filter_name,
$filter_ville,
$filter_departement,
$filter_region
),
$query->getInt('page', 1), /* page number */
25 /* limit per page */
);
return $this->render('Structure/index.html.twig', [
'name' => $filter_name,
'ville' => $filter_ville,
'filter_departement' => $filter_departement,
'filter_region' => $filter_region,
'pagination' => $pagination,
'title' => $title,
'type_structure' => $type_structure,
'departements' => $departements,
'regions' => $regions,
]);
}
/**
* Afficher les infos dans un modal.
*/
#[Route(path: '/showModal/{id}', name: 'show_modal_structure', methods: ['GET'])]
#[Route(path: '/showModal', name: 'show_modal_my_structure', methods: ['GET'])] // La variable $idModal permet de spécifier l'id de la class modal
public function showModal(?Structure $structure = null, $idModal = null): Response
{
if (is_null($structure)) {
$structure = $this->getUser()->getStructure();
if (is_null($structure)) {
throw $this->createNotFoundException('Unable to find Structure entity');
}
}
return $this->render('Structure/show_modal_information.html.twig', [
'idModal' => $idModal,
'entity' => $structure,
]);
}
/**
* Afficher les infos dans un modal.
*/
#[Route(path: '/show/{id}', name: 'show_structure', methods: ['GET'])]
#[Route(path: '/show', name: 'show_my_structure', methods: ['GET'])]
public function show(?Structure $structure = null): Response
{
if (false === $this->isGranted('ROLE_USER')) {
// throw new AccessDeniedException();
}
if (is_null($structure) || is_null($this->getUser())) {
if (is_null($this->getUser())) {
throw $this->createNotFoundException('Unable to find Structure entity');
}
$structure = $this->getUser()->getStructure();
if (is_null($structure)) {
throw $this->createNotFoundException('Unable to find Structure entity');
}
}
return $this->render('Structure/show.html.twig', [
'entity' => $structure,
]);
}
/**
* Afficher une carte avec les structures auquels le cso a droit.
*/
#[Route(path: '/map', name: 'map_structures', methods: ['GET'])]
public function showAuthMapStructure(Request $request): Response
{
$user = $this->getUser();
$structure = $user ? $user->getStructure() : null;
$query = $request->query;
$filter_name = $query->get('name', '');
$filter_ville = $query->get('ville', '');
$filter_departement = $query->get('departement', '');
$filter_region = $query->get('region', '');
$filter_structureTypes = $query->get('structureTypes', $this->getUser() ? [4] : [0]);
if ($this->getUser() && $this->isGranted('ROLE_ADMIN') && !$this->isGranted('ROLE_RN') && '' == $filter_region) {
if (($this->isGranted('ROLE_CAF') || $this->isGranted('ROLE_FDD')) && !$this->isGranted('ROLE_RR') && '' == $filter_departement) {
$filter_departement = $this->getUser()->getStructure()->getDepartement()->getId();
}
$filter_region = $this->getUser()->getStructure()->getRegion()->getId();
}
// recuperations des départements
$departements = $this->em->getRepository(Departement::class)->getAllByRegion($filter_region);
$regions = $this->em->getRepository(Region::class)->findAll();
$typesAuth = [
'2' => 'EVS',
'4' => 'CSO',
];
if ($this->getUser()) {
$typesAuth = [
'2' => 'EVS',
'4' => 'CSO',
'3' => 'CAF',
'5' => 'FDD',
];
}
$structuresArray = [];
if (count($filter_structureTypes) > 0) {
// récupération des structures authorisées
$structuresArray = [
'CSO' => $this->em->getRepository(Structure::class)->getListCoordinateStructureFormMap($structure, 4, $filter_name, $filter_ville, $filter_departement, $filter_region, $filter_structureTypes),
'EVS' => $this->em->getRepository(Structure::class)->getListCoordinateStructureFormMap($structure, 2, $filter_name, $filter_ville, $filter_departement, $filter_region, $filter_structureTypes),
];
if ($this->getUser()) {
$structuresArray['CAF'] = $this->em->getRepository(Structure::class)->getListCoordinateStructureFormMap($structure, 3, $filter_name, $filter_ville, $filter_departement, $filter_region, $filter_structureTypes);
$structuresArray['FDD'] = $this->em->getRepository(Structure::class)->getListCoordinateStructureFormMap($structure, 5, $filter_name, $filter_ville, $filter_departement, $filter_region, $filter_structureTypes);
}
}
return $this->render('Structure/map.html.twig', [
'structuresArray' => $structuresArray,
'name' => $filter_name,
'ville' => $filter_ville,
'filter_departement' => $filter_departement,
'filter_region' => $filter_region,
'filter_structureTypes' => $filter_structureTypes,
'departements' => $departements,
'regions' => $regions,
'typesAuth' => $typesAuth,
]);
}
/**
* Displays a form to edit an existing entity.
*/
#[Route(path: '/{id}/edit', name: 'structure_edit', methods: ['GET', 'POST'])]
public function edit(Request $request, StructureRepository $structureRepository, Structure $structure): Response
{
if (false === $this->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException();
}
$structure_id = $this->getUser()->getStructure()->getId();
if (!$this->isGranted('ROLE_ADMIN') && $structure_id != $structure->getId()) {
throw new AccessDeniedException('This user does not have access to this section.');
}
if (0 !== substr_count($structure->getEmail(), 'no_email-')) {
$structure->setEmail('');
}
$editForm = $this->createEditForm($structure);
if ('CSO' != $structure->getTypeStructure() && 'EVS' != $structure->getTypeStructure()) {
$editForm = $this->createForm(SimpleStructureType::class, $structure);
$editForm->remove('password');
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$structureRepository->add($structure);
if ($structure && $structure->getTypeStructure()) {
$user = $structure->getUser();
// recupration des rôles existants
$roles = $user->getRoles();
switch ($structure->getTypeStructure()) {
case 'EVS':
case 'CSO':
case 'FDD':
case 'CAF':
case 'RR':
case 'RGR':
case 'RN':
case 'DEP_LIGHT':
case 'REG_LIGHT':
$role = 'ROLE_'.$structure->getTypeStructure()->getNom();
break;
case 'RN_LIGHT':
$role = 'ROLE_DEP_LIGHT';
break;
default:
$role = 'ROLE_CSO';
break;
}
if (!in_array($role, $roles)) {
$user->setRoles([$role]);
$this->em->persist($user);
}
}
$this->em->flush();
}
}
return $this->render('Structure/edit.html.twig', [
'entity' => $structure,
'edit_form' => $editForm->createView(),
]);
}
/**
* Creates a form to edit a structure entity.
*
* @param Structure $entity The entity
*
* @return Form The form
*/
private function createEditForm(Structure $entity)
{
$form = $this->createForm(StructureType::class, $entity, [
'action' => $this->generateUrl(
'structure_update',
['id' => $entity->getId()]
),
'method' => 'POST',
'currentUser' => $this->getUser(),
]);
$form->add('submit', SubmitType::class, ['label' => 'Update']);
return $form;
}
/**
* Edits an existing ModeGestion entity.
*/
#[Route(path: '/{id}', name: 'structure_update', methods: ['POST'])]
public function update(Request $request, Structure $structure): RedirectResponse|Response
{
if (false === $this->isGranted('IS_AUTHENTICATED_FULLY')) {
throw new AccessDeniedException();
}
$structure_id = $this->getUser()->getStructure()->getId();
if (!$this->isGranted('ROLE_ADMIN') && $structure_id != $structure->getId()) {
throw new AccessDeniedException('This user does not have access to this section.');
}
$editForm = $this->createEditForm($structure);
$editForm->handleRequest($request);
$structureUser = $structure->getUser();
if ($editForm->isSubmitted() && $editForm->isValid()) {
if ($this->isGranted('ROLE_ADMIN') && ($structure && $structure->getTypeStructure())) {
$roles = $structureUser->getRoles();
switch ($structure->getTypeStructure()) {
case 'EVS':
case 'CSO':
case 'FDD':
case 'CAF':
case 'RR':
case 'RGR':
case 'RN':
case 'DEP_LIGHT':
case 'REG_LIGHT':
$role = 'ROLE_'.$structure->getTypeStructure()->getNom();
break;
case 'RN_LIGHT':
$role = 'ROLE_DEP_LIGHT';
break;
default:
$role = 'ROLE_CSO';
break;
}
if (!in_array($role, $roles)) {
$structureUser->setRoles([$role]);
$this->em->persist($structureUser);
}
}
$this->em->persist($structure);
$this->em->flush();
// test si email structure differente de mail user associé
if ($structureUser->getEmail() != $structure->getEmail()) {
// verification que l'adresse email n'est pas déjà utilisée dans la table fos_user
$findExistingEmail = $this->em->getRepository(User::class)->findOneBy(['email' => $structure->getEmail()]);
if (!$findExistingEmail) {
$structureUser->setEmail($structure->getEmail());
$this->em->persist($structureUser);
$this->em->flush();
}
}
// mise a jour des coordonnées geoloc eventuelles
$this->updateGeolocInfos($structure);
$this->affectCorrectDepartmentAndRegion($structure);
$this->get('session')->getFlashBag()->add('success', 'La fiche structure a été mise à jour avec succès');
return $this->redirectToRoute('show_structure', ['id' => $structure->getId()]);
}
return $this->render('Structure/edit.html.twig', [
'entity' => $structure,
'edit_form' => $editForm->createView(),
]);
}
private function updateGeolocInfos(Structure $structure): void
{
$geocoder = 'https://nominatim.openstreetmap.org/search.php?q=%s&format=json&addressdetails=1&limit=1&polygon_svg=1&email=contact@senacs.fr';
if ($structure->getCommuneImplementation()) {
$adresse = '';
if ($structure->getAdresse()) {
$adresse .= $structure->getAdresse().'+';
}
if ($structure->getCodePostal()) {
$adresse .= $structure->getCodePostal().'+';
}
$adresse .= $structure->getCommuneImplementation()->getNom().'+FRANCE';
// $url = sprintf($geocoder, urlencode($adresse));
$url = sprintf($geocoder, str_replace(' ', '+', $adresse));
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tmp = curl_exec($ch);
$result = json_decode($tmp, true);
$lat = null;
$lng = null;
/* if ($result['status'] === "OK") {
$lat = $result['results']['0']['geometry']['location']['lat'];
$lng = $result['results']['0']['geometry']['location']['lng'];
} */
if (is_array($result) && count($result)) {
$lat = $result['0']['lat'];
$lng = $result['0']['lon'];
}
if ($lat && $lng) {
$structure->setLatitude($lat);
$structure->setLongitude($lng);
$this->em->persist($structure);
$this->em->flush();
}
}
}
private function affectCorrectDepartmentAndRegion(Structure $structure): void
{
$commune = $structure->getCommuneImplementation();
if ($commune && $commune->getDepartement() && (($structure->getDepartement() && $commune->getDepartement()->getId() != $structure->getDepartement()->getId()) || !$structure->getDepartement())) {
$structure->setDepartement($commune->getDepartement());
if ($commune->getDepartement()->getRegion()) {
$structure->setRegion($commune->getDepartement()->getRegion());
$structure->setGrandeRegion($commune->getDepartement()->getRegion()->getGrandeRegion());
}
$this->em->persist($structure);
$this->em->flush();
}
}
}