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

2361
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

@ -128,14 +128,19 @@ final class AdminController extends AbstractController
// Récupérer les stats existantes pour la zone // Récupérer les stats existantes pour la zone
$stats_exist = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); $stats_exist = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if ($stats_exist) {
$stats = $stats_exist;
} else {
// Vérifier à nouveau pour éviter les race conditions
$stats_exist = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if ($stats_exist) { if ($stats_exist) {
$stats = $stats_exist; $stats = $stats_exist;
} else { } else {
$stats = new Stats(); $stats = new Stats();
// dump('nouvelle stat', $insee_code);
// die();
$stats->setZone($insee_code); $stats->setZone($insee_code);
$this->entityManager->persist($stats);
$this->entityManager->flush();
}
} }
$urls = $stats->getAllCTCUrlsMap(); $urls = $stats->getAllCTCUrlsMap();
@ -264,7 +269,7 @@ final class AdminController extends AbstractController
if ($place->getOsmId() == $placeData['id']) { if ($place->getOsmId() == $placeData['id']) {
// Mettre à jour les tags et coordonnées // Mettre à jour les tags et coordonnées
$place->update_place_from_overpass_data($placeData); $place->update_place_from_overpass_data($placeData);
$place->setStat($stats); $place->setStats($stats);
$stats->addPlace($place); $stats->addPlace($place);
$this->entityManager->persist($place); $this->entityManager->persist($place);
break; break;
@ -331,8 +336,31 @@ final class AdminController extends AbstractController
// Remove existing duplicates // Remove existing duplicates
$this->removeDuplicatePlaces($stats); $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 // labourer
$places_found = [];
try {
$places_found = $this->motocultrice->labourer($insee_code); $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)) { if (count($places_found)) {
// var_dump(count($places_found)); // var_dump(count($places_found));
$placeRepo = $this->entityManager->getRepository(Place::class); $placeRepo = $this->entityManager->getRepository(Place::class);
@ -378,7 +406,15 @@ final class AdminController extends AbstractController
// Update the places_count property // Update the places_count property
$stats->setPlacesCount($stats->getPlaces()->count()); $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(); $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()]); $this->actionLogger->log('stats_de_ville', ['insee_code' => $insee_code, 'nom' => $stats->getZone()]);
// Récupérer tous les commerces de la zone // Récupérer tous les commerces de la zone
// $commerces = $this->entityManager->getRepository(Place::class)->findBy(['zip_code' => $insee_code, 'dead' => false]); // $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) { if (!$stats) {
// Si aucune stat n'existe, on en crée une vide pour éviter les erreurs, mais sans la sauvegarder $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 = new Stats();
$stats->setZone($insee_code); $stats->setZone($insee_code);
$stats->setName('Nouvelle zone non labourée'); $stats->setName('Nouvelle zone non labourée');
$this->entityManager->persist($stats);
$this->entityManager->flush();
}
} }
$urls = $stats->getAllCTCUrlsMap(); $urls = $stats->getAllCTCUrlsMap();
@ -653,6 +696,9 @@ final class AdminController extends AbstractController
return $this->redirectToRoute('app_admin'); return $this->redirectToRoute('app_admin');
} }
// 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 // Créer un nouvel objet Stats avec les données de l'API
$stats = new Stats(); $stats = new Stats();
$stats->setZone($insee_code) $stats->setZone($insee_code)
@ -693,6 +739,7 @@ final class AdminController extends AbstractController
$this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.'); $this->addFlash('success', 'Nouvelle commune ajoutée à partir des données de l\'API geo.api.gouv.fr.');
} }
}
$themes = \App\Service\FollowUpService::getFollowUpThemes(); $themes = \App\Service\FollowUpService::getFollowUpThemes();
if (!isset($themes[$theme])) { if (!isset($themes[$theme])) {
@ -973,12 +1020,16 @@ final class AdminController extends AbstractController
return $this->redirectToRoute('app_public_index'); return $this->redirectToRoute('app_public_index');
} }
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]); $stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) {
// Vérifier à nouveau pour éviter les race conditions
$stats = $this->entityManager->getRepository(Stats::class)->findOneBy(['zone' => $insee_code]);
if (!$stats) { if (!$stats) {
$stats = new Stats(); $stats = new Stats();
$stats->setZone($insee_code); $stats->setZone($insee_code);
$stats->setKind('request'); // Set the kind to 'request' as it's created from an admin request $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.'); $this->entityManager->persist($stats);
// return $this->redirectToRoute('app_public_index'); $this->entityManager->flush();
}
} }
// Compléter le nom si manquant // Compléter le nom si manquant
if (!$stats->getName()) { if (!$stats->getName()) {

View file

@ -201,7 +201,11 @@ out meta;';
]); ]);
if ($response->getStatusCode() !== 200) { 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); $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": { "doctrine/doctrine-bundle": {
"version": "2.13", "version": "2.13",
"recipe": { "recipe": {
@ -204,6 +213,18 @@
"tests/bootstrap.php" "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": { "symfony/routing": {
"version": "6.2", "version": "6.2",
"recipe": { "recipe": {

View file

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

View file

@ -3,12 +3,33 @@
{% block title %}Dernières modifications{% endblock %} {% block title %}Dernières modifications{% endblock %}
{% block body %} {% 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> <h1>Dernières modifications</h1>
<div class="row"> <div class="row">
<div class="col-12 col-md-6 "> <div class="col-12 col-md-6 " id="modified_places">
<h2>Lieux modifiés</h2> <h2 >Lieux modifiés</h2>
<table class="table table-striped table-hover table-responsive table-sort"> <table class="table table-striped table-hover table-responsive table-sort">
<thead> <thead>
<tr> <tr>
@ -31,7 +52,7 @@
</table> </table>
</div> </div>
<div class="col-12 col-md-6 "> <div class="col-12 col-md-6 " id="displayed_places">
<h2>Lieux affichés</h2> <h2>Lieux affichés</h2>
<table class="table table-striped table-hover table-responsive table-sort"> <table class="table table-striped table-hover table-responsive table-sort">
<thead> <thead>
@ -54,5 +75,6 @@
</table> </table>
</div> </div>
</div> </div>
</div>
{% endblock %} {% endblock %}

View file

@ -18,6 +18,7 @@
<ul class="dropdown-menu" aria-labelledby="dataDropdown"> <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_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_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_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_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> <li><a class="dropdown-item" href="{{ path('app_public_latest_changes') }}"><i class="bi bi-clock-fill"></i> {{ 'display.latest_changes'|trans }}</a></li>