2025-05-26 11:55:44 +02:00
< ? php
namespace App\Controller ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController ;
use Symfony\Component\HttpFoundation\Response ;
use Symfony\Component\Routing\Attribute\Route ;
2025-05-26 12:57:10 +02:00
use App\Entity\Place ;
2025-05-26 23:51:46 +02:00
use App\Entity\Stats ;
2025-05-26 12:57:10 +02:00
use App\Service\Motocultrice ;
use Doctrine\ORM\EntityManagerInterface ;
use function uuid_create ;
2025-05-26 11:55:44 +02:00
final class AdminController extends AbstractController
{
2025-05-26 12:57:10 +02:00
public function __construct (
private EntityManagerInterface $entityManager ,
private Motocultrice $motocultrice
) {
}
2025-05-26 11:55:44 +02:00
#[Route('/admin', name: 'app_admin')]
public function index () : Response
{
return $this -> render ( 'admin/index.html.twig' , [
'controller_name' => 'AdminController' ,
]);
}
2025-05-26 12:57:10 +02:00
2025-05-26 23:51:46 +02:00
#[Route('/admin/stats/{zip_code}', name: 'app_admin_stats')]
public function calculer_stats ( string $zip_code ) : Response
{
// Récupérer tous les commerces de la zone
$commerces = $this -> entityManager -> getRepository ( Place :: class ) -> findBy ([ 'zip_code' => $zip_code ]);
// Récupérer les stats existantes pour la zone
$stats = $this -> entityManager -> getRepository ( Stats :: class ) -> findOneBy ([ 'zone' => $zip_code ]);
if ( ! $stats ) {
$stats = new Stats ();
$stats -> setZone ( $zip_code );
}
// Calculer les statistiques
$calculatedStats = $this -> motocultrice -> calculateStats ( $commerces );
// Mettre à jour les stats pour la zone donnée
$stats -> setPlacesCount ( $calculatedStats [ 'places_count' ]);
$stats -> setAvecHoraires ( $calculatedStats [ 'counters' ][ 'avec_horaires' ]);
$stats -> setAvecAdresse ( $calculatedStats [ 'counters' ][ 'avec_adresse' ]);
$stats -> setAvecSite ( $calculatedStats [ 'counters' ][ 'avec_site' ]);
$stats -> setAvecAccessibilite ( $calculatedStats [ 'counters' ][ 'avec_accessibilite' ]);
$stats -> setAvecNote ( $calculatedStats [ 'counters' ][ 'avec_note' ]);
$stats -> setCompletionPercent ( $calculatedStats [ 'completion_percent' ]);
// Associer les stats à chaque commerce
foreach ( $commerces as $commerce ) {
$commerce -> setStats ( $stats );
$this -> entityManager -> persist ( $commerce );
}
$this -> entityManager -> persist ( $stats );
$this -> entityManager -> flush ();
2025-05-27 12:17:46 +02:00
$stats -> computeCompletionPercent ();
$this -> entityManager -> persist ( $stats );
$this -> entityManager -> flush ();
2025-05-26 23:51:46 +02:00
return $this -> render ( 'admin/stats.html.twig' , [
'stats' => $stats ,
'zip_code' => $zip_code ,
2025-06-01 18:56:01 +02:00
'counters' => $calculatedStats [ 'counters' ],
'maptiler_token' => $_ENV [ 'MAPTILER_TOKEN' ],
'mapbox_token' => $_ENV [ 'MAPBOX_TOKEN' ],
2025-05-26 23:51:46 +02:00
]);
}
2025-06-01 23:35:15 +02:00
#[Route('/admin/placeType/{osm_kind}/{osm_id}', name: 'app_admin_by_osm_id')]
public function placeType ( string $osm_kind , string $osm_id ) : Response
{
$place = $this -> entityManager -> getRepository ( Place :: class ) -> findOneBy ([ 'osm_kind' => $osm_kind , 'osmId' => $osm_id ]);
if ( $place ) {
return $this -> redirectToRoute ( 'app_admin_commerce' , [ 'id' => $place -> getId ()]);
} else {
$this -> addFlash ( 'error' , 'Le lieu n\'existe pas.' );
return $this -> redirectToRoute ( 'app_public_index' );
}
}
2025-05-28 16:24:34 +02:00
#[Route('/admin/commerce/{id}', name: 'app_admin_commerce')]
public function commerce ( int $id ) : Response
{
// Vérifier si on est en prod
if ( $this -> getParameter ( 'kernel.environment' ) === 'prod' ) {
$this -> addFlash ( 'error' , 'Vous n\'avez pas accès à cette page en production.' );
return $this -> redirectToRoute ( 'app_public_index' );
}
$commerce = $this -> entityManager -> getRepository ( Place :: class ) -> find ( $id );
if ( ! $commerce ) {
throw $this -> createNotFoundException ( 'Commerce non trouvé' );
}
// Redirection vers la page de modification avec les paramètres nécessaires
return $this -> redirectToRoute ( 'app_public_edit' , [
'zipcode' => $commerce -> getZipCode (),
2025-05-29 13:24:50 +02:00
'name' => $commerce -> getName () != '' ? $commerce -> getName () : '?' ,
2025-05-28 16:24:34 +02:00
'uuid' => $commerce -> getUuidForUrl ()
]);
}
2025-05-26 12:57:10 +02:00
#[Route('/admin/labourer/{zip_code}', name: 'app_admin_labourer')]
public function labourer_zone ( string $zip_code ) : Response
{
$results = [];
// $zone = 'Briis sous forges';
$results = $this -> motocultrice -> labourer ( $zip_code );
// Récupérer les commerces existants dans la base de données pour cette zone
$commerces = $this -> entityManager -> getRepository ( Place :: class ) -> findBy ([ 'zip_code' => $zip_code ]);
2025-05-26 23:51:46 +02:00
// Récupérer ou créer les stats pour cette zone
$stats = $this -> entityManager -> getRepository ( Stats :: class ) -> findOneBy ([ 'zone' => $zip_code ]);
if ( ! $stats ) {
$stats = new Stats ();
$stats -> setZone ( $zip_code );
// for commerce, set stats
foreach ( $commerces as $commerce ) {
$commerce -> setStats ( $stats );
$this -> entityManager -> persist ( $commerce );
$stats -> addPlace ( $commerce );
}
// rebuild et persist
$stats -> computeCompletionPercent ();
$this -> entityManager -> persist ( $stats );
$this -> entityManager -> flush ();
}
2025-05-29 13:24:50 +02:00
$commerces = $this -> entityManager -> getRepository ( Place :: class ) -> findBy ([ 'zip_code' => $zip_code ]);
2025-05-26 23:51:46 +02:00
// Initialiser les compteurs
$counters = [
'avec_horaires' => 0 ,
'avec_adresse' => 0 ,
'avec_site' => 0 ,
'avec_accessibilite' => 0 ,
'avec_note' => 0
];
// Compter les différents critères pour chaque commerce
foreach ( $commerces as $commerce ) {
if ( $commerce -> hasOpeningHours ()) {
$counters [ 'avec_horaires' ] ++ ;
}
if ( $commerce -> hasAddress ()) {
$counters [ 'avec_adresse' ] ++ ;
}
if ( $commerce -> hasWebsite ()) {
$counters [ 'avec_site' ] ++ ;
}
if ( $commerce -> hasWheelchair ()) {
$counters [ 'avec_accessibilite' ] ++ ;
}
if ( $commerce -> hasNote ()) {
$counters [ 'avec_note' ] ++ ;
}
$commerce -> setStats ( $stats );
}
// Mettre à jour les statistiques
$stats -> setPlacesCount ( count ( $commerces ));
$stats -> setAvecHoraires ( $counters [ 'avec_horaires' ]);
$stats -> setAvecAdresse ( $counters [ 'avec_adresse' ]);
$stats -> setAvecSite ( $counters [ 'avec_site' ]);
$stats -> setAvecAccessibilite ( $counters [ 'avec_accessibilite' ]);
$stats -> setAvecNote ( $counters [ 'avec_note' ]);
$stats -> computeCompletionPercent ();
$this -> entityManager -> persist ( $stats );
$this -> entityManager -> flush ();
2025-05-26 12:57:10 +02:00
$osm_object_ids = [];
2025-05-26 23:51:46 +02:00
if ( $commerces ) {
2025-05-26 12:57:10 +02:00
// Extraire les osm_object_ids des commerces existants
$osm_object_ids = array_map ( function ( $commerce ) {
return $commerce -> getOsmId ();
}, $commerces );
}
// pour chaque résultat, vérifier que l'on a pas déjà un commerce avec le même osm_object_id
$results = array_filter ( $results , function ( $commerce ) use ( $osm_object_ids ) {
return ! in_array ( $commerce [ 'id' ], $osm_object_ids );
});
2025-05-26 23:51:46 +02:00
2025-05-26 12:57:10 +02:00
// on crée un commerce pour chaque résultat qui reste
foreach ( $results as $result ) {
$commerce = new Place ();
2025-06-01 19:52:56 +02:00
if ( isset ( $result [ 'tags' ][ 'amenity' ])) {
$commerce -> setMainTag ( 'amenity=' . $result [ 'tags' ][ 'amenity' ]);
}
if ( isset ( $result [ 'tags' ][ 'shop' ])) {
$commerce -> setMainTag ( 'shop=' . $result [ 'tags' ][ 'shop' ]);
}
if ( isset ( $result [ 'tags' ][ 'tourism' ])) {
$commerce -> setMainTag ( 'tourism=' . $result [ 'tags' ][ 'tourism' ]);
}
2025-05-26 12:57:10 +02:00
$commerce -> setOsmId ( $result [ 'id' ])
-> setOsmKind ( $result [ 'type' ])
-> setName ( $result [ 'name' ])
-> setZipCode ( $zip_code )
-> setEmail ( $result [ 'email' ])
-> setUuidForUrl ( $this -> motocultrice -> uuid_create ())
-> setOptedOut ( false )
-> setDead ( false )
2025-05-26 23:51:46 +02:00
2025-05-26 12:57:10 +02:00
-> setModifiedDate ( new \DateTime ())
-> setAskedHumainsSupport ( false )
-> setLastContactAttemptDate ( null )
2025-05-28 17:05:34 +02:00
-> setStats ( $stats )
2025-05-26 23:51:46 +02:00
-> setNote ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'note' ]) ? isset ( $result [ 'tags' ][ 'note' ]) : null )
-> setHasOpeningHours ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'opening_hours' ]) ? isset ( $result [ 'tags' ][ 'opening_hours' ]) : null )
-> setHasAddress (( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'address' ]) || $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'contact:address' ])) ? isset ( $result [ 'tags' ][ 'address' ]) : null )
-> setHasWebsite ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'website' ]) ? $result [ 'tags' ][ 'website' ] : null )
-> setHasWheelchair ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'wheelchair' ]) ? $result [ 'tags' ][ 'wheelchair' ] : null )
2025-06-01 23:35:15 +02:00
-> setHasNote ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'note' ]) ? $result [ 'tags' ][ 'note' ] : null )
-> setNoteContent ( $result [ 'tags' ] && isset ( $result [ 'tags' ][ 'note' ]) ? $result [ 'tags' ][ 'note' ] : null )
2025-05-26 23:51:46 +02:00
;
2025-05-26 12:57:10 +02:00
$this -> entityManager -> persist ( $commerce );
}
$this -> entityManager -> flush ();
2025-05-29 13:24:50 +02:00
$commerces = $this -> entityManager -> getRepository ( Place :: class ) -> findBy ([ 'zip_code' => $zip_code ]);
// var_dump($commerces[0]);
2025-05-26 12:57:10 +02:00
return $this -> render ( 'admin/labourage_results.html.twig' , [
'results' => $results ,
2025-05-26 23:51:46 +02:00
'commerces' => $commerces ,
2025-05-26 12:57:10 +02:00
'zone' => $zip_code ,
]);
}
2025-05-26 23:51:46 +02:00
#[Route('/admin/delete/{id}', name: 'app_admin_delete')]
public function delete ( int $id ) : Response
{
$commerce = $this -> entityManager -> getRepository ( Place :: class ) -> find ( $id );
2025-05-28 16:24:34 +02:00
if ( $commerce ) {
$this -> entityManager -> remove ( $commerce );
$this -> entityManager -> flush ();
2025-05-26 23:51:46 +02:00
2025-05-28 16:24:34 +02:00
$this -> addFlash ( 'success' , 'Le lieu ' . $commerce -> getName () . ' a été supprimé avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.' );
} else {
$this -> addFlash ( 'error' , 'Le lieu n\'existe pas.' );
}
2025-05-26 23:51:46 +02:00
2025-05-28 16:24:34 +02:00
return $this -> redirectToRoute ( 'app_public_dashboard' );
2025-05-26 23:51:46 +02:00
}
#[Route('/admin/delete_by_zone/{zip_code}', name: 'app_admin_delete_by_zone')]
public function delete_by_zone ( string $zip_code ) : Response
{
$commerces = $this -> entityManager -> getRepository ( Place :: class ) -> findBy ([ 'zip_code' => $zip_code ]);
2025-06-01 19:52:56 +02:00
$stats = $this -> entityManager -> getRepository ( Stats :: class ) -> findOneBy ([ 'zone' => $zip_code ]);
2025-05-26 23:51:46 +02:00
foreach ( $commerces as $commerce ) {
$this -> entityManager -> remove ( $commerce );
}
2025-06-01 19:52:56 +02:00
$this -> entityManager -> remove ( $stats );
2025-05-26 23:51:46 +02:00
$this -> entityManager -> flush ();
$this -> addFlash ( 'success' , 'Tous les commerces de la zone ' . $zip_code . ' ont été supprimés avec succès de OSM Mes commerces, mais pas dans OpenStreetMap.' );
2025-05-28 16:24:34 +02:00
return $this -> redirectToRoute ( 'app_public_dashboard' );
}
2025-05-26 23:51:46 +02:00
#[Route('/admin/export', name: 'app_admin_export')]
public function export () : Response
{
$places = $this -> entityManager -> getRepository ( Place :: class ) -> findAll ();
$csvData = [];
$csvData [] = [
'Nom' ,
'Email' ,
'Code postal' ,
'ID OSM' ,
'Type OSM' ,
'Date de modification' ,
'Date dernier contact' ,
'Note' ,
'Désabonné' ,
'Inactif' ,
'Support humain demandé' ,
'A des horaires' ,
'A une adresse' ,
'A un site web' ,
'A accessibilité' ,
'A une note'
];
foreach ( $places as $place ) {
$csvData [] = [
$place -> getName (),
$place -> getEmail (),
$place -> getZipCode (),
$place -> getOsmId (),
$place -> getOsmKind (),
$place -> getModifiedDate () ? $place -> getModifiedDate () -> format ( 'Y-m-d H:i:s' ) : '' ,
$place -> getLastContactAttemptDate () ? $place -> getLastContactAttemptDate () -> format ( 'Y-m-d H:i:s' ) : '' ,
$place -> getNote (),
$place -> isOptedOut () ? 'Oui' : 'Non' ,
$place -> isDead () ? 'Oui' : 'Non' ,
$place -> isAskedHumainsSupport () ? 'Oui' : 'Non' ,
$place -> hasOpeningHours () ? 'Oui' : 'Non' ,
$place -> hasAddress () ? 'Oui' : 'Non' ,
$place -> hasWebsite () ? 'Oui' : 'Non' ,
$place -> hasWheelchair () ? 'Oui' : 'Non' ,
$place -> hasNote () ? 'Oui' : 'Non'
];
}
$response = new Response ();
$response -> headers -> set ( 'Content-Type' , 'text/csv' );
$response -> headers -> set ( 'Content-Disposition' , 'attachment; filename="export_places.csv"' );
$handle = fopen ( 'php://temp' , 'r+' );
foreach ( $csvData as $row ) {
fputcsv ( $handle , $row , ';' );
}
rewind ( $handle );
$response -> setContent ( stream_get_contents ( $handle ));
fclose ( $handle );
return $response ;
}
2025-05-26 11:55:44 +02:00
}