diff --git a/README.md b/README.md index a93c14c..8090b85 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,6 @@ déployer sur un serveur ayant du php 8 créer un utilisateur et sa base -sudo -u postgres psql -c "CREATE USER sf WITH PASSWORD 'jkazhreiidfsDFgfgsgFHGSshdffdshefJYIyl';" +sudo -u postgres psql -c "CREATE USER sf WITH PASSWORD 'sfrgdHYJi56631lyshFSQGfd45452ùwdf54f8fg5dfhg5_tyfdgthIOPHFUGH';" sudo -u postgres psql -c "CREATE DATABASE \"osm-my-commerce\" OWNER sf;" diff --git a/composer.json b/composer.json index 03225ef..75f1cb1 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,8 @@ "doctrine/doctrine-migrations-bundle": "^3.4", "doctrine/orm": "^3.1", "guzzlehttp/guzzle": "^7.9", + "nyholm/psr7": "^1.8", + "php-http/discovery": "^1.20", "phpdocumentor/reflection-docblock": "^5.6", "phpstan/phpdoc-parser": "^2.1", "symfony/asset": "*", diff --git a/composer.lock b/composer.lock index 3a3817c..9949396 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f7625b2c7b49fdb113072ea857ae3f03", + "content-hash": "2ac1e47a82b3110fe5fa1449fc6ad0c5", "packages": [ { "name": "doctrine/collections", @@ -1620,6 +1620,163 @@ ], "time": "2025-03-24T10:02:05+00:00" }, + { + "name": "nyholm/psr7", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2024-09-09T07:06:30+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 1d45336..965dc41 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -6,6 +6,9 @@ framework: handle_all_throwables: true default_locale: 'fr' + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: ['fr'] # Enables session support. Note that the session will ONLY be started if you read or write from it. # Remove or comment this section to explicitly disable session support. diff --git a/config/packages/http_discovery.yaml b/config/packages/http_discovery.yaml new file mode 100644 index 0000000..2a789e7 --- /dev/null +++ b/config/packages/http_discovery.yaml @@ -0,0 +1,10 @@ +services: + Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory' + + http_discovery.psr17_factory: + class: Http\Discovery\Psr17Factory diff --git a/config/services.yaml b/config/services.yaml index 2d6a76f..208cc0d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -21,4 +21,7 @@ services: - '../src/Kernel.php' # add more service definitions when explicit configuration is needed + GuzzleHttp\Client: + class: GuzzleHttp\Client + # please note that last definitions always *replace* previous ones diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php new file mode 100644 index 0000000..2d25c75 --- /dev/null +++ b/src/Controller/AdminController.php @@ -0,0 +1,18 @@ +render('admin/index.html.twig', [ + 'controller_name' => 'AdminController', + ]); + } +} diff --git a/src/Controller/PublicController.php b/src/Controller/PublicController.php index 8d56cd3..a06d497 100644 --- a/src/Controller/PublicController.php +++ b/src/Controller/PublicController.php @@ -4,6 +4,7 @@ namespace App\Controller; use App\Entity\Stats; use App\Entity\Place; +use App\Service\Motocultrice; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; @@ -17,78 +18,17 @@ class PublicController extends AbstractController private $maptiler_token = 'BVM2NRJuzQunWvXbTnzg'; public function __construct( - private EntityManagerInterface $entityManager + private EntityManagerInterface $entityManager, + private Motocultrice $motocultrice ) { } - public function get_osm_object_data($osm_object_id = 12855459190) - { - - // TODO extraire ceci dans un service - $object_id = "https://www.openstreetmap.org/api/0.6/node/".$osm_object_id; - - $osm_object_data = [ - // "version"=> "0.6", - // "generator"=> "openstreetmap-cgimap 2.0.1 (2557185 spike-08.openstreetmap.org)", - // "copyright"=> "OpenStreetMap and contributors", - // "attribution"=> "http://www.openstreetmap.org/copyright", - // "license"=> "http://opendatacommons.org/licenses/odbl/1-0/", - // "elements"=> [ - // [ - // "type"=> "node", - // "id"=> 12855459190, - // "lat"=> 49.6504926, - // "lon"=> -1.5722526, - // "timestamp"=> "2025-05-22T13:15:45Z", - // "version"=> 1, - // "changeset"=> 166613142, - // "user"=> "tykayn", - // "uid"=> 2962129, - // "tags"=> [ - // "name"=> "Harry le potier", - // "tourism"=> "artwork" - // ] - // ] - // ] - ]; - - // Récupérer les vraies données OSM - $client = new Client(); - try { - $response = $client->get($object_id); - $xml = simplexml_load_string($response->getBody()->getContents()); - $json = json_encode($xml); - $osm_object_data = json_decode($json, true); - } catch (\Exception $e) { - // En cas d'erreur, on garde les données de test - $this->addFlash('warning', 'Impossible de récupérer les données OSM. Utilisation des données de test.'); - } - - // var_dump($osm_object_data['node']); - // die(); - - // convertir les tags en clés et valeurs - $osm_object_data['tags_converted'] = []; - - // var_dump($osm_object_data['node']['tag']); - - - foreach ($osm_object_data['node']['tag'] as $attribute) { - // var_dump($attribute['@attributes']['k']); - // die(); - - $osm_object_data['node']['tags_converted'][$attribute['@attributes']['k']] = $attribute['@attributes']['v']; - } - -// var_dump($osm_object_data['node']['tags_converted']); -// die(); - return $osm_object_data['node']; - } + #[Route('/', name: 'app_public_index')] public function index(): Response { - $commerce = $this->get_osm_object_data(); + $commerce = $this->motocultrice->get_osm_object_data(); return $this->render('public/index.html.twig', [ 'controller_name' => 'PublicController', 'commerce' => $commerce, @@ -212,7 +152,7 @@ class PublicController extends AbstractController } // après envoi on récupère les données - $commerce = $this->get_osm_object_data($osm_object_id); + $commerce = $this->motocultrice->get_osm_object_data($osm_object_id); return $this->render('public/view.html.twig', [ 'controller_name' => 'PublicController', 'commerce' => $commerce, diff --git a/src/Service/Motocultrice.php b/src/Service/Motocultrice.php new file mode 100644 index 0000000..d3bb34e --- /dev/null +++ b/src/Service/Motocultrice.php @@ -0,0 +1,91 @@ +.searchArea; + ( + nwr["shop"](area.searchArea); + ); + out body; + >; + out skel qt; + QUERY; + + try { + $response = $this->client->request('POST', $this->overpassApiUrl, [ + 'body' => ['data' => $query] + ]); + + $data = json_decode($response->getContent(), true); + + $shops = []; + if (isset($data['elements'])) { + foreach ($data['elements'] as $element) { + if (isset($element['tags']['shop'])) { + $shops[] = [ + 'id' => $element['id'], + 'type' => $element['type'], + 'name' => $element['tags']['name'] ?? 'Sans nom', + 'shop_type' => $element['tags']['shop'], + 'lat' => $element['lat'] ?? null, + 'lon' => $element['lon'] ?? null, + 'tags' => $element['tags'] + ]; + } + } + } + + return $shops; + } 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) + { + $object_id = "https://www.openstreetmap.org/api/0.6/node/".$osm_object_id; + + try { + $response = $this->client->request('GET', $object_id); + $xml = simplexml_load_string($response->getContent()); + $json = json_encode($xml); + $osm_object_data = json_decode($json, true); + } catch (\Exception $e) { + throw new \Exception("Impossible de récupérer les données OSM : " . $e->getMessage()); + } + + // 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']; + } + + return $osm_object_data['node']; + } + + public function semer(): string + { + return "La motocultrice sème les graines"; + } + + public function récolter(): string + { + return "La motocultrice récolte les cultures"; + } +} \ No newline at end of file diff --git a/symfony.lock b/symfony.lock index d7a5af9..abf16fb 100644 --- a/symfony.lock +++ b/symfony.lock @@ -38,6 +38,18 @@ "migrations/.gitignore" ] }, + "php-http/discovery": { + "version": "1.20", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "1.18", + "ref": "f45b5dd173a27873ab19f5e3180b2f661c21de02" + }, + "files": [ + "config/packages/http_discovery.yaml" + ] + }, "phpunit/phpunit": { "version": "9.6", "recipe": { diff --git a/templates/admin/index.html.twig b/templates/admin/index.html.twig new file mode 100644 index 0000000..d9a2644 --- /dev/null +++ b/templates/admin/index.html.twig @@ -0,0 +1,20 @@ +{% extends 'base.html.twig' %} + +{% block title %}Hello AdminController!{% endblock %} + +{% block body %} + + +
+

Hello {{ controller_name }}! ✅

+ + This friendly message is coming from: + +
+{% endblock %} diff --git a/templates/base.html.twig b/templates/base.html.twig index 382891d..b102a8f 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -13,9 +13,6 @@ {{ encore_entry_link_tags('app') }} {% endblock %} - {% block javascripts %} - {{ encore_entry_script_tags('app') }} - {% endblock %}
@@ -44,4 +41,8 @@ + + {% block javascripts %} + {{ encore_entry_script_tags('app') }} + {% endblock %} diff --git a/templates/public/index.html.twig b/templates/public/index.html.twig index b7155e6..64df3b5 100644 --- a/templates/public/index.html.twig +++ b/templates/public/index.html.twig @@ -1,6 +1,6 @@ {% extends 'base.html.twig' %} -{% block title %}Hello PublicController!{% endblock %} +{% block title %}{{ 'display.title'|trans }}{% endblock %} {% block stylesheets %} {{ parent() }} @@ -24,13 +24,13 @@ @@ -43,12 +43,10 @@
-

Bienvenue dans les commerces!

-
+

{{ 'display.welcome'|trans }}

+
{% if commerce is not empty %} - -{# {{dump(commerce)}} #}
@@ -57,56 +55,55 @@
-
-

Tags

+

{{ 'display.tags'|trans }}

{% for attributes in commerce.tag %} {% for kv in attributes %} - {% if kv.k is 'opening_hours' %} - - {{ 'display.keys.' ~ kv.k |trans}} - - + {% if kv.k == 'opening_hours' %} + {{ 'display.keys.opening_hours'|trans }} {% else %} -
-
- - {{ 'display.keys.' ~ kv.k |trans}} +
+
+ + {{ ('display.keys.' ~ kv.k)|trans }} +
+
+ +
-
- -
-
{% endif %} {% endfor %} {% endfor %} - -
- +
{% endif %}
- -Dernière modification: {{ commerce['@attributes'].timestamp }} par {{ commerce['@attributes'].user }} - + + {{ '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 }} + +

- Attention: - Ce site est un travail en cours, ceci est une démonstration sur un objet fictif qui utilise les données de l'API OpenStreetMap. + {{ 'display.disclaimer.title'|trans }}: + {{ 'display.disclaimer.text'|trans }}

@@ -116,13 +113,10 @@ diff --git a/translations/fr.yaml b/translations/fr.yaml deleted file mode 100644 index 47fd24c..0000000 --- a/translations/fr.yaml +++ /dev/null @@ -1,18 +0,0 @@ -display: - contact_humans: "Contacter des humains d'OSM France pour m'aider" - modify: "Modifier" - keys: - - "tags" : "étiquettes" - - "name" : "Nom" - - "address" : "Adresse" - - "phone" : "Téléphone" - - "email" : "Email" - - "contact:phone" : "Téléphone du contact" - - "address:housenumber" : "Numéro de rue" - - "address:street" : "Rue" - - "address:city" : "Ville" - - "address:postcode" : "Code postal" - - "website" : "Site web" - - "contact:website" : "Contact du Site web" - - "opening_hours" : "Horaires d'ouverture" - - "shop" : "Type de commerce" \ No newline at end of file diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml new file mode 100644 index 0000000..aacf144 --- /dev/null +++ b/translations/messages.en.yaml @@ -0,0 +1,33 @@ +display: + title: "OSM My Shop" + home: "Home" + stats: "Statistics" + contact_humans: "Contact OSM France humans for help" + modify: "Modify" + welcome: "Welcome to the shops!" + modify_commerce: "Modify your shop" + tags: "Tags" + submit: "Submit" + last_modification: "Last modification" + days_ago: "%days% days ago" + by: "by" + view_on_osm: "View on OpenStreetMap" + keys: + tags: "tags" + name: "Name" + address: "Address" + phone: "Phone" + contact:email: "Email" + contact:phone: "Contact phone" + address:housenumber: "Street number" + address:street: "Street" + address:city: "City" + address:postcode: "Postal code" + website: "Website" + contact:website: "Contact website" + opening_hours: "Opening hours" + shop: "Shop type" + tourism: "Tourism" + disclaimer: + title: "Warning" + text: "This site is a work in progress, this is a demonstration on a fictional object using OpenStreetMap API data." \ No newline at end of file diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml new file mode 100644 index 0000000..293b088 --- /dev/null +++ b/translations/messages.fr.yaml @@ -0,0 +1,33 @@ +display: + title: "OSM Mon Commerce" + home: "Accueil" + stats: "Statistiques" + contact_humans: "Contacter des humains d'OSM France pour m'aider" + modify: "Modifier" + welcome: "Bienvenue dans les commerces!" + modify_commerce: "Modifier votre commerce" + tags: "Tags" + submit: "Envoyer" + last_modification: "Dernière modification" + days_ago: "il y a %days% jours" + by: "par" + view_on_osm: "Voir sur OpenStreetMap" + keys: + tags: "étiquettes" + name: "Nom" + address: "Adresse" + phone: "Téléphone" + contact:email: "Email" + contact:phone: "Téléphone du contact" + address:housenumber: "Numéro de rue" + address:street: "Rue" + address:city: "Ville" + address:postcode: "Code postal" + website: "Site web" + contact:website: "Contact du Site web" + opening_hours: "Horaires d'ouverture" + shop: "Type de commerce" + tourism: "Tourisme" + disclaimer: + title: "Attention" + text: "Ce site est un travail en cours, ceci est une démonstration sur un objet fictif qui utilise les données de l'API OpenStreetMap."