diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php index 2d25c75..478369e 100644 --- a/src/Controller/AdminController.php +++ b/src/Controller/AdminController.php @@ -5,9 +5,22 @@ namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; +use App\Entity\Place; + +use App\Service\Motocultrice; +use Doctrine\ORM\EntityManagerInterface; +use function uuid_create; final class AdminController extends AbstractController { + + public function __construct( + private EntityManagerInterface $entityManager, + private Motocultrice $motocultrice + ) { + } + + #[Route('/admin', name: 'app_admin')] public function index(): Response { @@ -15,4 +28,56 @@ final class AdminController extends AbstractController 'controller_name' => 'AdminController', ]); } + + #[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]); + + $osm_object_ids = []; + + if ($commerces) { + // 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); + }); + + // on crée un commerce pour chaque résultat qui reste + foreach ($results as $result) { + $commerce = new Place(); + $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) + ->setNote($result['note'] ?? null) + ->setModifiedDate(new \DateTime()) + ->setAskedHumainsSupport(false) + ->setLastContactAttemptDate(null) + ->setStats(null); + $this->entityManager->persist($commerce); + } + + $this->entityManager->flush(); + + return $this->render('admin/labourage_results.html.twig', [ + 'results' => $results, + 'zone' => $zip_code, + ]); + } } diff --git a/src/Controller/PublicController.php b/src/Controller/PublicController.php index a06d497..3a38861 100644 --- a/src/Controller/PublicController.php +++ b/src/Controller/PublicController.php @@ -37,6 +37,20 @@ class PublicController extends AbstractController ]); } + #[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) { + return $this->redirectToRoute('app_public_index'); + } + $commerce = $this->motocultrice->get_osm_object_data($place->getOsmKind(), $place->getOsmId()); + return $this->render('public/edit.html.twig', [ + 'commerce' => $commerce, + 'name' => $name, + ]); + } + #[Route('/dashboard', name: 'app_public_dashboard')] public function dashboard(): Response { diff --git a/src/Service/Motocultrice.php b/src/Service/Motocultrice.php index d3bb34e..19a379f 100644 --- a/src/Service/Motocultrice.php +++ b/src/Service/Motocultrice.php @@ -3,28 +3,48 @@ namespace App\Service; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Doctrine\ORM\EntityManagerInterface; class Motocultrice { private $overpassApiUrl = 'https://overpass-api.de/api/interpreter'; public function __construct( - private HttpClientInterface $client + private HttpClientInterface $client, + private EntityManagerInterface $entityManager ) { } public function labourer(string $zone): array { + if (!$zone) { + throw new \InvalidArgumentException("La zone ne peut pas être vide"); + } + + // Nettoyer et échapper la zone pour la requête + $zone = addslashes(trim($zone)); + $query = <<.searchArea; + area["postal_code"="{$zone}"]->.searchArea; ( - nwr["shop"](area.searchArea); + // Recherche des commerces et services avec email + nw["amenity"]["contact:email"](area.searchArea); + nw["amenity"]["email"](area.searchArea); + nw["shop"]["contact:email"](area.searchArea); + nw["shop"]["email"](area.searchArea); + nw["office"]["contact:email"](area.searchArea); + nw["office"]["email"](area.searchArea); + + // Recherche des commerces et services sans email pour référence + nw["amenity"](area.searchArea); + nw["shop"](area.searchArea); + nw["office"](area.searchArea); ); out body; >; out skel qt; - QUERY; +QUERY; try { $response = $this->client->request('POST', $this->overpassApiUrl, [ @@ -33,15 +53,21 @@ class Motocultrice $data = json_decode($response->getContent(), true); - $shops = []; + $places = []; if (isset($data['elements'])) { foreach ($data['elements'] as $element) { - if (isset($element['tags']['shop'])) { - $shops[] = [ + if (isset($element['tags'])) { + $email = $element['tags']['contact:email'] ?? $element['tags']['email'] ?? null; + // On passe si pas d'email + if (!$email) { + continue; + } + + $places[] = [ 'id' => $element['id'], 'type' => $element['type'], - 'name' => $element['tags']['name'] ?? 'Sans nom', - 'shop_type' => $element['tags']['shop'], + 'name' => $element['tags']['name'] ?? '', + 'email' => $email, 'lat' => $element['lat'] ?? null, 'lon' => $element['lon'] ?? null, 'tags' => $element['tags'] @@ -50,15 +76,15 @@ class Motocultrice } } - return $shops; + return $places; } catch (\Exception $e) { throw new \Exception("Erreur lors de la requête Overpass : " . $e->getMessage()); } } - public function get_osm_object_data($osm_object_id = 12855459190) + public function get_osm_object_data($osm_kind = 'node', $osm_object_id = 12855459190) { - $object_id = "https://www.openstreetmap.org/api/0.6/node/".$osm_object_id; + $object_id = "https://www.openstreetmap.org/api/0.6/".$osm_kind."/".$osm_object_id; try { $response = $this->client->request('GET', $object_id); @@ -71,21 +97,48 @@ class Motocultrice // convertir les tags en clés et valeurs $osm_object_data['tags_converted'] = []; - - foreach ($osm_object_data['node']['tag'] as $attribute) { - $osm_object_data['node']['tags_converted'][$attribute['@attributes']['k']] = $attribute['@attributes']['v']; + // Initialiser le tableau des tags convertis + if (isset($osm_object_data['node'])) { + $osm_object_data['node']['tags_converted'] = []; + } elseif (isset($osm_object_data['way'])) { + $osm_object_data['way']['tags_converted'] = []; + } + if(isset($osm_object_data['node'])){ + foreach ($osm_object_data['node']['tag'] as $attribute) { + $osm_object_data['node']['tags_converted'][$attribute['@attributes']['k']] = $attribute['@attributes']['v']; + } + return $osm_object_data['node']; + } + if(isset($osm_object_data['way'])){ + foreach ($osm_object_data['way']['tag'] as $attribute) { + $osm_object_data['way']['tags_converted'][$attribute['@attributes']['k']] = $attribute['@attributes']['v']; + } + return $osm_object_data['way']; } - return $osm_object_data['node']; + return $osm_object_data; } + - public function semer(): string - { - return "La motocultrice sème les graines"; - } + public function uuid_create() { + return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', + // 32 bits for "time_low" + mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), - public function récolter(): string - { - return "La motocultrice récolte les cultures"; - } + // 16 bits for "time_mid" + mt_rand( 0, 0xffff ), + + // 16 bits for "time_hi_and_version", + // four most significant bits holds version number 4 + mt_rand( 0, 0x0fff ) | 0x4000, + + // 16 bits, 8 bits for "clk_seq_hi_res", + // 8 bits for "clk_seq_low", + // two most significant bits holds zero and one for variant DCE1.1 + mt_rand( 0, 0x3fff ) | 0x8000, + + // 48 bits for "node" + mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) + ); +} } \ No newline at end of file diff --git a/templates/admin/index.html.twig b/templates/admin/index.html.twig index d9a2644..0001148 100644 --- a/templates/admin/index.html.twig +++ b/templates/admin/index.html.twig @@ -10,11 +10,6 @@

Hello {{ controller_name }}! ✅

- - This friendly message is coming from: - +
{% endblock %} diff --git a/templates/admin/labourage_results.html.twig b/templates/admin/labourage_results.html.twig new file mode 100644 index 0000000..cffa05c --- /dev/null +++ b/templates/admin/labourage_results.html.twig @@ -0,0 +1,25 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello AdminController!{% endblock %} + +{% block body %} + + +
+

Labourage fait sur la zone "{{ zone }}" ✅

+ +{# {{ dump(results) }} #} + {% for commerce in results %} +

+ {{ commerce.name }} +

+
+            {{ dump(commerce) }}
+        
+ {% endfor %} + +
+{% endblock %} diff --git a/templates/public/dashboard.html.twig b/templates/public/dashboard.html.twig index bc4723a..1cef998 100644 --- a/templates/public/dashboard.html.twig +++ b/templates/public/dashboard.html.twig @@ -48,7 +48,9 @@ Email Date de modification Date de dernier contact - Date de dernière modification + Date de dernière modification + Code postal + @@ -61,7 +63,17 @@ {{ place.modifiedDate | date('Y-m-d H:i:s') }} {{ place.lastContactAttemptDate | date('Y-m-d H:i:s') }} {{ place.modifiedDate | date('Y-m-d H:i:s') }} - + {{ place.zipCode }} + + Voir dans OSM + + {% if place.name %} + Modifier + {% else %} + Modifier + {% endif %} + + {% endfor %} diff --git a/templates/public/edit.html.twig b/templates/public/edit.html.twig new file mode 100644 index 0000000..64df3b5 --- /dev/null +++ b/templates/public/edit.html.twig @@ -0,0 +1,151 @@ +{% extends 'base.html.twig' %} + +{% block title %}{{ 'display.title'|trans }}{% endblock %} + +{% block stylesheets %} + {{ parent() }} + + +{% endblock %} + +{% block body %} +
+ + +
+
+
+
+

{{ 'display.welcome'|trans }}

+
+ + {% if commerce is not empty %} +
+
+ +
+
+ +
+
+ +
+ + {{ 'display.contact_humans'|trans }} +
+ +

{{ 'display.tags'|trans }}

+
+ {% for attributes in commerce.tag %} + {% for kv in attributes %} + {% if kv.k == 'opening_hours' %} + {{ 'display.keys.opening_hours'|trans }} + {% else %} +
+
+ + {{ ('display.keys.' ~ kv.k)|trans }} +
+
+ +
+
+ {% endif %} + {% endfor %} + {% endfor %} +
+ + +
+ {% endif %} +
+
+
+ + {{ 'display.last_modification'|trans }}: {{ commerce['@attributes'].timestamp }}, + {{ 'display.days_ago'|trans({'%days%': date(commerce['@attributes'].timestamp).diff(date()).days}) }} + {{ 'display.by'|trans }} + {{ commerce['@attributes'].user }} + + + +
+

+ {{ 'display.disclaimer.title'|trans }}: + {{ 'display.disclaimer.text'|trans }} +

+
+
+ + +
+ +{% block javascripts %} + {{ parent() }} + {# #} + {# #} +{% endblock %} +{% endblock %} diff --git a/templates/public/index.html.twig b/templates/public/index.html.twig index 64df3b5..f657702 100644 --- a/templates/public/index.html.twig +++ b/templates/public/index.html.twig @@ -46,47 +46,7 @@

{{ 'display.welcome'|trans }}

- {% if commerce is not empty %} -
-
- -
-
- -
-
- -
- - {{ 'display.contact_humans'|trans }} -
- -

{{ 'display.tags'|trans }}

-
- {% for attributes in commerce.tag %} - {% for kv in attributes %} - {% if kv.k == 'opening_hours' %} - {{ 'display.keys.opening_hours'|trans }} - {% else %} -
-
- - {{ ('display.keys.' ~ kv.k)|trans }} -
-
- -
-
- {% endif %} - {% endfor %} - {% endfor %} -
- - -
- {% endif %} +