motocultrice->get_osm_object_data(); return $this->render('public/index.html.twig', [ 'controller_name' => 'PublicController', 'commerce' => $commerce, 'mapbox_token' => $_ENV['MAPBOX_TOKEN'], 'maptiler_token' => $_ENV['MAPTILER_TOKEN'], ]); } #[Route('/edit/{zipcode}/{name}/{uuid}', name: 'app_public_edit')] public function edit_with_uuid($zipcode, $name, $uuid): Response { $place = $this->entityManager->getRepository(Place::class)->findOneBy(['uuid_for_url' => $uuid]); if (!$place) { $this->addFlash('warning', 'Ce lien de modification n\'existe pas.'); return $this->redirectToRoute('app_public_index'); } if ($place->getOsmKind() === 'relation') { $this->addFlash('warning', 'Les objets OSM de type "relation" ne sont pas gérés dans cet outil.'); return $this->redirectToRoute('app_public_index'); } // récupérer les tags de base $base_tags = $this->motocultrice->base_tags; $base_tags = array_fill_keys($base_tags, ''); $commerce_overpass = $this->motocultrice->get_osm_object_data($place->getOsmKind(), $place->getOsmId()); // Fusionner les tags de base avec les tags existants $commerce_overpass['tags_converted'] = array_merge($base_tags, $commerce_overpass['tags_converted']); // Trier les tags par ordre alphabétique des clés ksort($commerce_overpass['tags_converted']); return $this->render('public/edit.html.twig', [ 'commerce_overpass' => $commerce_overpass, 'name' => $name, 'commerce' => $place, 'hide_filled_inputs' => $this->hide_filled_inputs, 'excluded_tags_to_render' => $this->motocultrice->excluded_tags_to_render, 'osm_kind' => $place->getOsmKind(), "mapbox_token" => $_ENV['MAPBOX_TOKEN'], "maptiler_token" => $_ENV['MAPTILER_TOKEN'], ]); } #[Route('/dashboard', name: 'app_public_dashboard')] public function dashboard(): Response { // get stats $stats = $this->entityManager->getRepository(Stats::class)->findAll(); $places = $this->entityManager->getRepository(Place::class)->findBy([], ['zip_code' => 'ASC', 'name' => 'ASC']); return $this->render('public/dashboard.html.twig', [ 'controller_name' => 'PublicController', 'stats' => $stats, 'places' => $places, ]); } #[Route('/modify/{osm_object_id}/{version}/{changesetID}', name: 'app_public_submit')] public function submit($osm_object_id, $version, $changesetID): Response { // Récupérer les données POST $request = Request::createFromGlobals(); // Vérifier si des données ont été soumises if ($request->isMethod('POST')) { $status = "non modifié"; // Récupérer le type d'objet (node ou way) $osm_kind = $request->request->get('osm_kind', 'node'); // Récupérer tous les tags du formulaire $tags = []; $request_post = $request->request->all(); $request_post = $this->motocultrice->map_post_values($request_post); foreach ($request_post as $key => $value) { if (strpos($key, 'commerce_tag_value__') === 0) { $tagKey = str_replace('commerce_tag_value__', '', $key); if (!empty($value)) { // Validation des données selon le type de tag if ($tagKey === 'addr:postcode') { // Vérifier que c'est bien un code postal français (5 chiffres) if (!preg_match('/^\d{5}$/', $value)) { $status = "Erreur : Le code postal doit être composé de 5 chiffres"; continue; } } elseif ($tagKey === 'contact:phone' || $tagKey === 'phone') { // Nettoyer le numéro de téléphone $value = preg_replace('/[^0-9+]/', '', $value); } elseif (strpos($value, 'http://') === 0) { $value = str_replace('http://', 'https://', $value); } $tags[$tagKey] = $value; } } } // Récupérer le token OSM depuis les variables d'environnement $osm_api_token = $_ENV['APP_OSM_BEARER']; $exception = false; $exception_message = ""; try { $client = new Client(); // 1. Créer un nouveau changeset $changesetXml = new \SimpleXMLElement(''); $changeset = $changesetXml->addChild('changeset'); $tag = $changeset->addChild('tag'); $tag->addAttribute('k', 'created_by'); $tag->addAttribute('v', 'OSM Mon Commerce Web Editor'); $tag = $changeset->addChild('tag'); $tag->addAttribute('k', 'comment'); $tag->addAttribute('v', 'Modification des tags via l\'interface web #MonCommerceOSM'); $changesetResponse = $client->put('https://api.openstreetmap.org/api/0.6/changeset/create', [ 'body' => $changesetXml->asXML(), 'headers' => [ 'Authorization' => 'Bearer ' . $osm_api_token, 'Content-Type' => 'application/xml' ] ]); $newChangesetId = $changesetResponse->getBody()->getContents(); // Récupérer les données actuelles de l'objet $currentObjectData = $this->motocultrice->get_osm_object_data($osm_kind, $osm_object_id); // 2. Modifier l'objet avec le nouveau changeset $xml = new \SimpleXMLElement(''); $object = $xml->addChild($osm_kind); $object->addAttribute('id', $osm_object_id); $object->addAttribute('version', $version); $object->addAttribute('changeset', $newChangesetId); // Ajouter les coordonnées pour les nodes if ($osm_kind === 'node') { if (!isset($currentObjectData['@attributes']['lat']) || !isset($currentObjectData['@attributes']['lon'])) { throw new \Exception("Impossible de récupérer les coordonnées du nœud"); } $object->addAttribute('lat', $currentObjectData['@attributes']['lat']); $object->addAttribute('lon', $currentObjectData['@attributes']['lon']); } // Ajouter les tags foreach ($tags as $key => $value) { if (!empty($key) && !empty($value)) { $tag = $object->addChild('tag'); $tag->addAttribute('k', htmlspecialchars($key, ENT_XML1)); $tag->addAttribute('v', htmlspecialchars($value, ENT_XML1)); } } // Debug du XML généré $xmlString = $xml->asXML(); // echo('xml :
'.$xmlString); $response = $client->put("https://api.openstreetmap.org/api/0.6/{$osm_kind}/" . $osm_object_id, [ 'body' => $xmlString, 'headers' => [ 'Authorization' => 'Bearer ' . $osm_api_token, 'Content-Type' => 'application/xml' ] ]); // 3. Fermer le changeset $client->put('https://api.openstreetmap.org/api/0.6/changeset/' . $newChangesetId . '/close', [ 'headers' => [ 'Authorization' => 'Bearer ' . $osm_api_token ] ]); if ($response->getStatusCode() === 200) { $status = "Les tags ont été mis à jour avec succès"; } else { $status = "Erreur lors de la mise à jour des tags"; } } catch (\Exception $e) { $status = "Erreur lors de la communication avec l'API OSM: " . $e->getMessage(); $exception = true; $exception_message = $e->getMessage(); // Debug de la réponse en cas d'erreur if (method_exists($e, 'getResponse')) { var_dump($e->getResponse()->getBody()->getContents()); } } } // après envoi on récupère les données $commerce = $this->motocultrice->get_osm_object_data($osm_kind, $osm_object_id); return $this->render('public/view.html.twig', [ 'controller_name' => 'PublicController', 'commerce' => $commerce, 'status' => $status, 'exception' => $exception, 'exception_message' => $exception_message, 'mapbox_token' => $_ENV['MAPBOX_TOKEN'], 'maptiler_token' => $_ENV['MAPTILER_TOKEN'], ]); } #[Route('/request_email_to_modify/{osm_object_id}', name: 'app_public_request_email')] public function request_email($osm_object_id): Response { if ($this->getRequest()->isMethod('POST')) { $email = $this->getRequest()->request->get('email'); try { // TODO: Implémenter l'envoi réel du mail $this->addFlash( 'success', 'Un email vous a été envoyé avec les instructions pour modifier ce lieu.' ); } catch (\Exception $e) { $this->addFlash( 'error', 'Une erreur est survenue lors de l\'envoi de l\'email. Veuillez réessayer plus tard.' ); } return $this->redirectToRoute('app_public_index'); } // TODO envoyer un email return $this->render('public/request_email.html.twig', [ 'controller_name' => 'PublicController', 'commerce_id' => $osm_object_id, ]); } }