upgrade to symfony 7.3

This commit is contained in:
Tykayn 2025-11-19 22:44:21 +01:00 committed by tykayn
parent 971b95b299
commit 0448d3cc17
9 changed files with 1481 additions and 1125 deletions

View file

@ -94,7 +94,7 @@
},
"extra": {
"symfony": {
"require" : "7.0.*",
"require" : "7.3.*",
"allow-contrib": false,
"require": "*",
"endpoint": ["https://raw.githack.com/symfony/recipes/flex/main/index.json"]
@ -103,12 +103,12 @@
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.1",
"fakerphp/faker": "^1.24",
"phpunit/phpunit": "^9.5",
"phpunit/phpunit": "*",
"symfony/browser-kit": "*",
"symfony/css-selector": "*",
"symfony/debug-bundle": "*",
"symfony/maker-bundle": "^1.63",
"symfony/phpunit-bridge": "^7.2",
"symfony/maker-bundle": "*",
"symfony/phpunit-bridge": "*",
"symfony/stopwatch": "*",
"symfony/web-profiler-bundle": "*"
}

2375
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,3 @@
framework:
property_info:
with_constructor_extractor: true

View file

@ -131,11 +131,16 @@ final class AdminController extends AbstractController
if ($stats_exist) {
$stats = $stats_exist;
} else {
$stats = new Stats();
// dump('nouvelle stat', $insee_code);
// die();
$stats->setZone($insee_code);
// Vérifier à nouveau pour éviter les race conditions
$stats_exist = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if ($stats_exist) {
$stats = $stats_exist;
} else {
$stats = new Stats();
$stats->setZone($insee_code);
$this->entityManager->persist($stats);
$this->entityManager->flush();
}
}
$urls = $stats->getAllCTCUrlsMap();
@ -264,7 +269,7 @@ final class AdminController extends AbstractController
if ($place->getOsmId() == $placeData['id']) {
// Mettre à jour les tags et coordonnées
$place->update_place_from_overpass_data($placeData);
$place->setStat($stats);
$place->setStats($stats);
$stats->addPlace($place);
$this->entityManager->persist($place);
break;
@ -331,8 +336,31 @@ final class AdminController extends AbstractController
// Remove existing duplicates
$this->removeDuplicatePlaces($stats);
// S'assurer que $stats est bien géré par Doctrine et a un ID (est persistée)
if (!$this->entityManager->contains($stats) || !$stats->getId()) {
// Si $stats n'est pas géré ou n'a pas d'ID, on le récupère depuis le repository
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
$this->addFlash('error', 'Aucune stats trouvée pour ce code INSEE.');
return $this->redirectToRoute('app_admin_import_stats');
}
}
// labourer
$places_found = $this->motocultrice->labourer($insee_code);
$places_found = [];
try {
$places_found = $this->motocultrice->labourer($insee_code);
} catch (\Exception $e) {
// Gérer les erreurs de l'API Overpass (timeout, etc.)
$errorMessage = $e->getMessage();
if (strpos($errorMessage, '504') !== false || strpos($errorMessage, 'timeout') !== false) {
$this->addFlash('warning', 'L\'API Overpass a expiré (timeout). La zone est peut-être trop grande ou le serveur est surchargé. Les données existantes sont affichées, mais les nouveaux lieux ne peuvent pas être chargés pour le moment. Veuillez réessayer plus tard.');
} else {
$this->addFlash('warning', 'Erreur lors de la récupération des données depuis l\'API Overpass : ' . $errorMessage);
}
// On continue avec un tableau vide pour ne pas bloquer l'affichage de la page
}
if (count($places_found)) {
// var_dump(count($places_found));
$placeRepo = $this->entityManager->getRepository(Place::class);
@ -378,7 +406,15 @@ final class AdminController extends AbstractController
// Update the places_count property
$stats->setPlacesCount($stats->getPlaces()->count());
// $this->entityManager->persist($stats);
}
// S'assurer que $stats est toujours géré et a un ID avant le flush
if (!$this->entityManager->contains($stats) || !$stats->getId()) {
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
$this->addFlash('error', 'Erreur : impossible de récupérer les stats.');
return $this->redirectToRoute('app_admin_import_stats');
}
}
$this->entityManager->flush();
@ -386,11 +422,18 @@ final class AdminController extends AbstractController
$this->actionLogger->log('stats_de_ville', ['insee_code' => $insee_code, 'nom' => $stats->getZone()]);
// Récupérer tous les commerces de la zone
// $commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code, 'dead' => false]);
// $stats devrait toujours exister ici car on l'a récupéré au début de la méthode
// Si ce n'est pas le cas, on récupère depuis le repository
if (!$stats) {
// Si aucune stat n'existe, on en crée une vide pour éviter les erreurs, mais sans la sauvegarder
$stats = new Stats();
$stats->setZone($insee_code);
$stats->setName('Nouvelle zone non labourée');
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
// Si vraiment aucune stat n'existe, on en crée une vide pour éviter les erreurs
$stats = new Stats();
$stats->setZone($insee_code);
$stats->setName('Nouvelle zone non labourée');
$this->entityManager->persist($stats);
$this->entityManager->flush();
}
}
$urls = $stats->getAllCTCUrlsMap();
@ -653,45 +696,49 @@ final class AdminController extends AbstractController
return $this->redirectToRoute('app_admin');
}
// Créer un nouvel objet Stats avec les données de l'API
$stats = new Stats();
$stats->setZone($insee_code)
->setName($communeData['nom'])
->setDateCreated(new \DateTime())
->setDateModified(new \DateTime())
->setKind('request');
// Ajouter la population si disponible
if (isset($communeData['population'])) {
$stats->setPopulation($communeData['population']);
// Vérifier à nouveau si la Stats n'existe pas (éviter les race conditions)
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
// Créer un nouvel objet Stats avec les données de l'API
$stats = new Stats();
$stats->setZone($insee_code)
->setName($communeData['nom'])
->setDateCreated(new \DateTime())
->setDateModified(new \DateTime())
->setKind('request');
// Ajouter la population si disponible
if (isset($communeData['population'])) {
$stats->setPopulation($communeData['population']);
}
// Ajouter les coordonnées si disponibles
if (isset($communeData['centre']) && isset($communeData['centre']['coordinates'])) {
$stats->setLon((string)$communeData['centre']['coordinates'][0]);
$stats->setLat((string)$communeData['centre']['coordinates'][1]);
}
// Ajouter les codes postaux si disponibles
if (isset($communeData['codesPostaux']) && !empty($communeData['codesPostaux'])) {
$stats->setCodesPostaux(implode(',', $communeData['codesPostaux']));
}
// Ajouter le code EPCI si disponible
if (isset($communeData['codeEpci'])) {
$stats->setCodeEpci((int)$communeData['codeEpci']);
}
// Ajouter le SIREN si disponible
if (isset($communeData['siren'])) {
$stats->setSiren((int)$communeData['siren']);
}
// Persister l'objet Stats
$this->entityManager->persist($stats);
$this->entityManager->flush();
$this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.');
}
// Ajouter les coordonnées si disponibles
if (isset($communeData['centre']) && isset($communeData['centre']['coordinates'])) {
$stats->setLon((string)$communeData['centre']['coordinates'][0]);
$stats->setLat((string)$communeData['centre']['coordinates'][1]);
}
// Ajouter les codes postaux si disponibles
if (isset($communeData['codesPostaux']) && !empty($communeData['codesPostaux'])) {
$stats->setCodesPostaux(implode(',', $communeData['codesPostaux']));
}
// Ajouter le code EPCI si disponible
if (isset($communeData['codeEpci'])) {
$stats->setCodeEpci((int)$communeData['codeEpci']);
}
// Ajouter le SIREN si disponible
if (isset($communeData['siren'])) {
$stats->setSiren((int)$communeData['siren']);
}
// Persister l'objet Stats
$this->entityManager->persist($stats);
$this->entityManager->flush();
$this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.');
}
$themes = \App\Service\FollowUpService::getFollowUpThemes();
@ -974,11 +1021,15 @@ final class AdminController extends AbstractController
}
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
$stats = new Stats();
$stats->setZone($insee_code);
$stats->setKind('request'); // Set the kind to 'request' as it's created from an admin request
// $this->addFlash('error', '3 Aucune stats trouvée pour ce code INSEE.');
// return $this->redirectToRoute('app_public_index');
// Vérifier à nouveau pour éviter les race conditions
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
$stats = new Stats();
$stats->setZone($insee_code);
$stats->setKind('request'); // Set the kind to 'request' as it's created from an admin request
$this->entityManager->persist($stats);
$this->entityManager->flush();
}
}
// Compléter le nom si manquant
if (!$stats->getName()) {

View file

@ -201,7 +201,11 @@ out meta;';
]);
if ($response->getStatusCode() !== 200) {
throw new \Exception('L\'API Overpass a retourné un code de statut non-200 : ' . $response->getStatusCode());
$statusCode = $response->getStatusCode();
if ($statusCode === 504) {
throw new \Exception('L\'API Overpass a expiré (timeout 504). La zone est peut-être trop grande ou le serveur est surchargé. Veuillez réessayer plus tard.');
}
throw new \Exception('L\'API Overpass a retourné un code de statut non-200 : ' . $statusCode);
}
$data = json_decode($response->getContent(), true);

View file

@ -1,4 +1,13 @@
{
"doctrine/deprecations": {
"version": "1.1",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "1.0",
"ref": "87424683adc81d7dc305eefec1fced883084aab9"
}
},
"doctrine/doctrine-bundle": {
"version": "2.13",
"recipe": {
@ -204,6 +213,18 @@
"tests/bootstrap.php"
]
},
"symfony/property-info": {
"version": "7.3",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "7.3",
"ref": "dae70df71978ae9226ae915ffd5fad817f5ca1f7"
},
"files": [
"config/packages/property_info.yaml"
]
},
"symfony/routing": {
"version": "6.2",
"recipe": {

View file

@ -44,6 +44,9 @@
margin-right: 8px;
}
.city-list a:nth-of-type(even) {
background-color:rgb(231, 231, 231);
}
.city-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));

View file

@ -3,12 +3,33 @@
{% block title %}Dernières modifications{% endblock %}
{% block body %}
<style>
#last_modifications {
margin-top: 2rem;
margin-bottom: 2rem;
border-left: 3px solid grey;
padding: 1rem;
}
#modified_places {
margin-bottom: 2rem;
border-left: 3px solid grey;
background-color: #f0f0f0;
padding: 1rem;
}
#displayed_places {
margin-bottom: 2rem;
border-left: 3px solid grey;
padding: 1rem;
background-color: #f0f0f0;
}
</style>
<div id="last_modifications">
<h1>Dernières modifications</h1>
<div class="row">
<div class="col-12 col-md-6 ">
<h2>Lieux modifiés</h2>
<div class="col-12 col-md-6 " id="modified_places">
<h2 >Lieux modifiés</h2>
<table class="table table-striped table-hover table-responsive table-sort">
<thead>
<tr>
@ -31,7 +52,7 @@
</table>
</div>
<div class="col-12 col-md-6 ">
<div class="col-12 col-md-6 " id="displayed_places">
<h2>Lieux affichés</h2>
<table class="table table-striped table-hover table-responsive table-sort">
<thead>
@ -54,5 +75,6 @@
</table>
</div>
</div>
</div>
{% endblock %}

View file

@ -18,6 +18,7 @@
<ul class="dropdown-menu" aria-labelledby="dataDropdown">
<li><a class="dropdown-item" href="{{ path('app_public_dashboard') }}"><i class="bi bi-bar-chart-fill"></i> {{ 'display.stats'|trans }}</a></li>
<li><a class="dropdown-item" href="{{ path('app_public_cities') }}"><i class="bi bi-geo-alt-fill"></i> Suivi des villes</a></li>
<li><a class="dropdown-item" href="{{ path('app_public_add_city') }}"><i class="bi bi-plus-circle-fill"></i> Ajouter une ville</a></li>
<li><a class="dropdown-item" href="{{ path('app_public_closed_commerces') }}"><i class="bi bi-x-circle-fill"></i> {{ 'display.closed_commerces'|trans }}</a></li>
<li><a class="dropdown-item" href="{{ path('app_public_places_with_note') }}"><i class="bi bi-file-earmark-text"></i> {{ 'display.places_with_note'|trans }}</a></li>
<li><a class="dropdown-item" href="{{ path('app_public_latest_changes') }}"><i class="bi bi-clock-fill"></i> {{ 'display.latest_changes'|trans }}</a></li>