diff --git a/src/Doctrine/ORM/GeocodeEntityListener.php b/src/Doctrine/ORM/GeocodeEntityListener.php index 239ae3d..c2d10ba 100644 --- a/src/Doctrine/ORM/GeocodeEntityListener.php +++ b/src/Doctrine/ORM/GeocodeEntityListener.php @@ -107,6 +107,16 @@ private function geocodeEntity(ClassMetadata $metadata, object $entity): void $result = $results->first(); $metadata->latitudeProperty?->setValue($entity, $result->getCoordinates()->getLatitude()); $metadata->longitudeProperty?->setValue($entity, $result->getCoordinates()->getLongitude()); + $metadata->northProperty?->setValue($entity, $result->getBounds()?->getNorth()); + $metadata->southProperty?->setValue($entity, $result->getBounds()?->getSouth()); + $metadata->eastProperty?->setValue($entity, $result->getBounds()?->getEast()); + $metadata->westProperty?->setValue($entity, $result->getBounds()?->getWest()); + $metadata->streetNumberProperty?->setValue($entity, $result->getStreetNumber()); + $metadata->streetNameProperty?->setValue($entity, $result->getStreetName()); + $metadata->localityProperty?->setValue($entity, $result->getLocality()); + $metadata->postalCodeProperty?->setValue($entity, $result->getPostalCode()); + $metadata->subLocalityProperty?->setValue($entity, $result->getSubLocality()); + $metadata->countryProperty?->setValue($entity, $result->getCountry()); } } diff --git a/src/Mapping/Attributes/Country.php b/src/Mapping/Attributes/Country.php new file mode 100644 index 0000000..dfb6c43 --- /dev/null +++ b/src/Mapping/Attributes/Country.php @@ -0,0 +1,16 @@ + 'latitudeProperty', + Attributes\Longitude::class => 'longitudeProperty', + Attributes\Address::class => 'addressProperty', + Attributes\North::class => 'northProperty', + Attributes\South::class => 'southProperty', + Attributes\East::class => 'eastProperty', + Attributes\West::class => 'westProperty', + Attributes\StreetNumber::class => 'streetNumberProperty', + Attributes\StreetName::class => 'streetNameProperty', + Attributes\Locality::class => 'localityProperty', + Attributes\PostalCode::class => 'postalCodeProperty', + Attributes\SubLocality::class => 'subLocalityProperty', + Attributes\Country::class => 'countryProperty', + ]; + public function isGeocodeable(object $object): bool { $reflection = self::getReflection($object); @@ -47,12 +63,8 @@ public function loadMetadataFromObject(object $object): ClassMetadata foreach ($reflection->getProperties() as $property) { foreach ($property->getAttributes() as $attribute) { - if (Attributes\Latitude::class === $attribute->getName()) { - $args['latitudeProperty'] = $property; - } elseif (Attributes\Longitude::class === $attribute->getName()) { - $args['longitudeProperty'] = $property; - } elseif (Attributes\Address::class === $attribute->getName()) { - $args['addressProperty'] = $property; + if (isset(self::PROPERTY_MATRIX[$attribute->getName()])) { + $args[self::PROPERTY_MATRIX[$attribute->getName()]] = $property; } } } diff --git a/tests/Functional/Fixtures/Entity/DummyWithProperty.php b/tests/Functional/Fixtures/Entity/DummyWithProperty.php index df222c9..c4201bc 100644 --- a/tests/Functional/Fixtures/Entity/DummyWithProperty.php +++ b/tests/Functional/Fixtures/Entity/DummyWithProperty.php @@ -13,9 +13,19 @@ namespace Bazinga\GeocoderBundle\Tests\Functional\Fixtures\Entity; use Bazinga\GeocoderBundle\Mapping\Attributes\Address; +use Bazinga\GeocoderBundle\Mapping\Attributes\Country; +use Bazinga\GeocoderBundle\Mapping\Attributes\East; use Bazinga\GeocoderBundle\Mapping\Attributes\Geocodeable; use Bazinga\GeocoderBundle\Mapping\Attributes\Latitude; +use Bazinga\GeocoderBundle\Mapping\Attributes\Locality; use Bazinga\GeocoderBundle\Mapping\Attributes\Longitude; +use Bazinga\GeocoderBundle\Mapping\Attributes\North; +use Bazinga\GeocoderBundle\Mapping\Attributes\PostalCode; +use Bazinga\GeocoderBundle\Mapping\Attributes\South; +use Bazinga\GeocoderBundle\Mapping\Attributes\StreetName; +use Bazinga\GeocoderBundle\Mapping\Attributes\StreetNumber; +use Bazinga\GeocoderBundle\Mapping\Attributes\SubLocality; +use Bazinga\GeocoderBundle\Mapping\Attributes\West; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; @@ -42,4 +52,44 @@ class DummyWithProperty #[Column(type: Types::STRING)] #[Address] public ?string $address = null; + + #[Column(type: Types::FLOAT, nullable: true)] + #[North] + public ?float $north = null; + + #[Column(type: Types::FLOAT, nullable: true)] + #[South] + public ?float $south = null; + + #[Column(type: Types::FLOAT, nullable: true)] + #[East] + public ?float $east = null; + + #[Column(type: Types::FLOAT, nullable: true)] + #[West] + public ?float $west = null; + + #[Column(type: Types::STRING, nullable: true)] + #[StreetNumber] + public int|string|null $streetNumber = null; + + #[Column(type: Types::STRING, nullable: true)] + #[StreetName] + public ?string $streetName = null; + + #[Column(type: Types::STRING, nullable: true)] + #[Locality] + public ?string $locality = null; + + #[Column(type: Types::STRING, nullable: true)] + #[PostalCode] + public ?string $postalCode = null; + + #[Column(type: Types::STRING, nullable: true)] + #[SubLocality] + public ?string $subLocality = null; + + #[Column(type: Types::STRING, nullable: true)] + #[Country] + public ?string $country = null; } diff --git a/tests/Functional/GeocodeEntityListenerTest.php b/tests/Functional/GeocodeEntityListenerTest.php index e55a756..166dfda 100644 --- a/tests/Functional/GeocodeEntityListenerTest.php +++ b/tests/Functional/GeocodeEntityListenerTest.php @@ -37,6 +37,9 @@ */ final class GeocodeEntityListenerTest extends KernelTestCase { + private const QUERY_BERLIN = 'Brandenburger Tor Berlin, Germany'; + private const QUERY_PARIS = 'Tour Eiffel Paris, France'; + protected function tearDown(): void { /** @var EntityManagerInterface $em */ @@ -118,7 +121,7 @@ public function testPersistForProperty(): void $container->set('http_client', self::createHttpClientForBerlinQuery()); $dummy = new DummyWithProperty(); - $dummy->address = 'Berlin, Germany'; + $dummy->address = self::QUERY_BERLIN; /** @var EntityManagerInterface $em */ $em = $container->get('doctrine.orm.entity_manager'); @@ -131,15 +134,35 @@ public function testPersistForProperty(): void self::assertNotNull($dummy->latitude); self::assertNotNull($dummy->longitude); + self::assertNotNull($dummy->north); + self::assertNotNull($dummy->south); + self::assertNotNull($dummy->east); + self::assertNotNull($dummy->west); + self::assertNotNull($dummy->streetNumber); + self::assertNotNull($dummy->streetName); + self::assertNotNull($dummy->locality); + self::assertNotNull($dummy->postalCode); + self::assertNotNull($dummy->subLocality); + self::assertNotNull($dummy->country); $clone = clone $dummy; - $dummy->address = 'Paris, France'; + $dummy->address = self::QUERY_PARIS; $em->persist($dummy); $em->flush(); self::assertNotEquals($clone->latitude, $dummy->latitude); self::assertNotEquals($clone->longitude, $dummy->longitude); + self::assertNotEquals($clone->north, $dummy->north); + self::assertNotEquals($clone->south, $dummy->south); + self::assertNotEquals($clone->east, $dummy->east); + self::assertNotEquals($clone->west, $dummy->west); + self::assertNotEquals($clone->streetNumber, $dummy->streetNumber); + self::assertNotEquals($clone->streetName, $dummy->streetName); + self::assertNotEquals($clone->locality, $dummy->locality); + self::assertNotEquals($clone->postalCode, $dummy->postalCode); + self::assertNotEquals($clone->subLocality, $dummy->subLocality); + self::assertNotEquals($clone->country, $dummy->country); } public function testPersistForGetter(): void @@ -160,7 +183,7 @@ public function testPersistForGetter(): void $tool->createSchema($em->getMetadataFactory()->getAllMetadata()); $dummy = new DummyWithGetter(); - $dummy->setAddress('Berlin, Germany'); + $dummy->setAddress(self::QUERY_BERLIN); $em->persist($dummy); $em->flush(); @@ -169,7 +192,7 @@ public function testPersistForGetter(): void self::assertNotNull($dummy->getLongitude()); $clone = clone $dummy; - $dummy->setAddress('Paris, France'); + $dummy->setAddress(self::QUERY_PARIS); $em->persist($dummy); $em->flush(); @@ -195,7 +218,7 @@ public function testPersistForStringableGetter(): void $tool = new SchemaTool($em); $tool->createSchema($em->getMetadataFactory()->getAllMetadata()); - $dummy = new DummyWithStringableGetter(new StringableAddress('Berlin, Germany')); + $dummy = new DummyWithStringableGetter(new StringableAddress(self::QUERY_BERLIN)); $em->persist($dummy); $em->flush(); @@ -204,7 +227,7 @@ public function testPersistForStringableGetter(): void self::assertNotNull($dummy->longitude); $clone = clone $dummy; - $dummy->setAddress(new StringableAddress('Paris, France')); + $dummy->setAddress(new StringableAddress(self::QUERY_PARIS)); $em->persist($dummy); $em->flush(); @@ -233,7 +256,7 @@ public function testPersistForInvalidGetter(): void $tool->createSchema($em->getMetadataFactory()->getAllMetadata()); $dummy = new DummyWithInvalidGetter(); - $dummy->setAddress('Berlin, Germany'); + $dummy->setAddress(self::QUERY_BERLIN); $em->persist($dummy); @@ -310,16 +333,16 @@ public function testDoesNotGeocodeIfAddressNotChanged(): void private static function createHttpClientForBerlinQuery(): MockHttpClient { return new MockHttpClient(static function (string $method, string $url): MockResponse { - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === $url) { + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Brandenburger%20Tor%20Berlin%2C%20Germany&addressdetails=1&extratags=1&limit=5' === $url) { self::assertSame('GET', $method); - return new MockResponse('[{"place_id":159647018,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":62422,"lat":"52.5170365","lon":"13.3888599","category":"boundary","type":"administrative","place_rank":8,"importance":0.7875390282491362,"addresstype":"city","name":"Berlin","display_name":"Berlin, Deutschland","address":{"city":"Berlin","ISO3166-2-lvl4":"DE-BE","country":"Deutschland","country_code":"de"},"extratags":{"ele": "35", "email": "info@berlin.de", "place": "city", "capital": "yes", "website": "http://www.berlin.de", "de:place": "city", "ref:nuts": "DE3;DE30;DE300", "wikidata": "Q64", "wikipedia": "de:Berlin", "population": "3769962", "ref:LOCODE": "DEBER", "ref:nuts:1": "DE3", "ref:nuts:2": "DE30", "ref:nuts:3": "DE300", "state_code": "BE", "name:prefix": "Land und Kreisfreie Stadt", "linked_place": "city", "official_status": "Land", "contact:facebook": "http://www.facebook.com/Berlin", "name:prefix:city": "Kreisfreie Stadt", "openGeoDB:loc_id": "14356", "capital_ISO3166-1": "yes", "name:prefix:state": "Land", "source:population": "https://download.statistik-berlin-brandenburg.de/fa93e3bd19a2e885/a5ecfb2fff6a/SB_A01-05-00_2020h02_BE.pdf", "license_plate_code": "B", "official_status:de": "Land", "official_status:en": "State", "official_status:ru": "земля", "geographical_region": "Barnim;Berliner Urstromtal;Teltow;Nauener Platte", "blind:description:de": "Auf www.berlinfuerblinde.de gibt es einen kostenlosen Audioguide und weitere Informationen.", "de:regionalschluessel": "110000000000", "openGeoDB:postal_codes": "10178,10115,10117,10119,10179,10243,10245,10247,10249,10315,10317,10318,10319,10365,10367,10369,10405,10407,10409,10435,10437,10439,10551,10553,10555,10557,10559,10585,10587,10589,10623,10625,10627,10629,10707,10709,10711,10713,10715,10717,10719,10777,10", "report_problems:website": "https://ordnungsamt.berlin.de/", "TMC:cid_58:tabcd_1:Class": "Area", "openGeoDB:license_plate_code": "B", "TMC:cid_58:tabcd_1:LCLversion": "12.0", "openGeoDB:telephone_area_code": "030", "TMC:cid_58:tabcd_1:LocationCode": "266", "de:amtlicher_gemeindeschluessel": "11000000", "openGeoDB:community_identification_number": "11000000"},"boundingbox":["52.3382448","52.6755087","13.0883450","13.7611609"]}]', ['response_headers' => ['content-type' => 'application/json']]); + return new MockResponse('[{"place_id":134111822,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"way","osm_id":518071791,"lat":"52.5162699","lon":"13.3777034","category":"historic","type":"monument","place_rank":30,"importance":0.5504719991549523,"addresstype":"historic","name":"Porte de Brandebourg","display_name":"Porte de Brandebourg, 1, Pariser Platz, Friedrich-Wilhelm-Stadt, Mitte, Berlin, 10117, Allemagne","address":{"historic":"Porte de Brandebourg","house_number":"1","road":"Pariser Platz","quarter":"Friedrich-Wilhelm-Stadt","suburb":"Mitte","borough":"Mitte","city":"Berlin","ISO3166-2-lvl4":"DE-BE","postcode":"10117","country":"Allemagne","country_code":"de"},"extratags":{"image": "http://upload.wikimedia.org/wikipedia/commons/7/71/Brandenburger_Tor_2005_006.JPG", "height": "26", "image:0": "https://photos.app.goo.gl/58KgcLTZ3qNYYhjc8", "ref:lda": "09065019", "tourism": "attraction", "building": "gate", "heritage": "4", "landmark": "20", "wikidata": "Q82425", "architect": "Carl Gotthard Langhans", "direction": "W", "wikipedia": "de:Brandenburger Tor", "start_date": "1788..1791", "wheelchair": "yes", "lda:criteria": "Baudenkmal", "opening_hours": "24/7", "heritage:website": "https://denkmaldatenbank.berlin.de/daobj.php?obj_dok_nr=09065019", "heritage:operator": "lda", "wikimedia_commons": "Category:Brandenburg Gate", "architect:wikidata": "Q313181", "toilets:wheelchair": "no", "architect:wikipedia": "de:Carl Gotthard Langhans", "heritage:description": "Baudenkmal", "construction:start_date": "1788"},"boundingbox":["52.5161170","52.5164328","13.3775798","13.3778251"]},{"place_id":133613781,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"node","osm_id":3862767512,"lat":"52.5166047","lon":"13.3809897","category":"railway","type":"station","place_rank":30,"importance":0.42779598793275175,"addresstype":"railway","name":"Brandenburger Tor","display_name":"Brandenburger Tor, Unter den Linden, Friedrich-Wilhelm-Stadt, Mitte, Berlin, 10117, Allemagne","address":{"railway":"Brandenburger Tor","road":"Unter den Linden","quarter":"Friedrich-Wilhelm-Stadt","suburb":"Mitte","borough":"Mitte","city":"Berlin","ISO3166-2-lvl4":"DE-BE","postcode":"10117","country":"Allemagne","country_code":"de"},"extratags":{"level": "-3", "subway": "yes", "station": "subway", "wikidata": "Q477185", "wikipedia": "de:Bahnhof Berlin Brandenburger Tor", "start_date": "2009-08-09", "wheelchair": "yes", "public_transport": "station"},"boundingbox":["52.5116047","52.5216047","13.3759897","13.3859897"]},{"place_id":134207485,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"node","osm_id":30353086,"lat":"52.5164415","lon":"13.3818418","category":"railway","type":"halt","place_rank":30,"importance":0.42779598793275175,"addresstype":"railway","name":"Brandenburger Tor","display_name":"Brandenburger Tor, Unter den Linden, Friedrich-Wilhelm-Stadt, Mitte, Berlin, 10117, Allemagne","address":{"railway":"Brandenburger Tor","road":"Unter den Linden","quarter":"Friedrich-Wilhelm-Stadt","suburb":"Mitte","borough":"Mitte","city":"Berlin","ISO3166-2-lvl4":"DE-BE","postcode":"10117","country":"Allemagne","country_code":"de"},"extratags":{"network": "Verkehrsverbund Berlin-Brandenburg", "station": "light_rail", "uic_ref": "8089044", "operator": "DB Netz AG", "wikidata": "Q477185", "wikipedia": "de:Bahnhof Berlin Brandenburger Tor", "light_rail": "yes", "wheelchair": "no", "railway:ref": "BTOR", "contact:phone": "+49 30 297 43333", "network:short": "VBB", "contact:website": "http://www.s-bahn-berlin.de/fahrplanundnetz/bahnhof/brandenburger-tor/153", "public_transport": "station", "railway:station_category": "4"},"boundingbox":["52.5163915","52.5164915","13.3817918","13.3818918"]}]', ['response_headers' => ['content-type' => 'application/json']]); } - if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Paris%2C%20France&addressdetails=1&extratags=1&limit=5' === $url) { + if ('https://nominatim.openstreetmap.org/search?format=jsonv2&q=Tour%20Eiffel%20Paris%2C%20France&addressdetails=1&extratags=1&limit=5' === $url) { self::assertSame('GET', $method); - return new MockResponse('[{"place_id":115350921,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":7444,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":15,"importance":0.8317101715588673,"addresstype":"suburb","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"suburb":"Paris","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"capital": "yes", "wikidata": "Q90", "ref:INSEE": "75056", "wikipedia": "fr:Paris", "population": "2187526", "ref:FR:MGP": "T1", "source:population": "INSEE 2020"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114827617,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":71525,"lat":"48.8534951","lon":"2.3483915","category":"boundary","type":"administrative","place_rank":12,"importance":0.8317101715588673,"addresstype":"city","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"rank": "0", "capital": "yes", "ref:nuts": "FR101", "wikidata": "Q90", "ref:INSEE": "75", "wikipedia": "fr:Paris", "is_capital": "country", "population": "2165423", "ref:nuts:3": "FR101", "linked_place": "city", "source:name:oc": "ieo-bdtopoc", "contact:website": "http://www.paris.fr", "population:date": "2019", "capital_ISO3166-1": "yes", "source:population": "INSEE 2022"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]},{"place_id":114994164,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"relation","osm_id":1641193,"lat":"48.8588897","lon":"2.3200410217200766","category":"boundary","type":"administrative","place_rank":14,"importance":0.4283953917728152,"addresstype":"city_district","name":"Paris","display_name":"Paris, Île-de-France, France métropolitaine, France","address":{"city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","country":"France","country_code":"fr"},"extratags":{"wikidata": "Q2863958", "ref:INSEE": "751", "wikipedia": "fr:Arrondissement de Paris"},"boundingbox":["48.8155755","48.9021560","2.2241220","2.4697602"]}]', ['response_headers' => ['content-type' => 'application/json']]); + return new MockResponse('[{"place_id":89233259,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"way","osm_id":5013364,"lat":"48.8582599","lon":"2.2945006","category":"man_made","type":"tower","place_rank":30,"importance":0.6205937724353116,"addresstype":"man_made","name":"Tour Eiffel","display_name":"Tour Eiffel, 5, Avenue Anatole France, Quartier du Gros-Caillou, Paris 7e Arrondissement, Paris, Île-de-France, France métropolitaine, 75007, France","address":{"man_made":"Tour Eiffel","house_number":"5","road":"Avenue Anatole France","city_block":"Quartier du Gros-Caillou","suburb":"Paris 7e Arrondissement","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75C","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","postcode":"75007","country":"France","country_code":"fr"},"extratags":{"fee": "10-25€", "3dmr": "4", "image": "https://fr.wikipedia.org/wiki/Fichier:Tour_Eiffel_Wikimedia_Commons.jpg", "layer": "2", "height": "330", "image:0": "https://photos.app.goo.gl/y43gmbzPz7jToV9D7", "ref:mhs": "PA00088801", "tourism": "attraction", "website": "https://www.toureiffel.paris/", "building": "tower", "engineer": "Gustave Eiffel;Maurice Koechlin;Émile Nouguier", "heritage": "3", "historic": "monument", "landmark": "1", "operator": "Société d’Exploitation de la Tour Eiffel", "wikidata": "Q243", "architect": "Stephen Sauvestre", "panoramax": "b57848f0-a526-4bab-8cb3-ede3df7b41c3;7e69687f-3956-41f2-bd85-03af73df2b2b;7ca4fd32-0e0a-498f-826c-d106ee360948&xyz=3.20/53.64/30", "wikipedia": "fr:Tour Eiffel", "importance": "international", "min_height": "0", "start_date": "1889", "tower:type": "communication;observation", "wheelchair": "no", "ref:FR:ANFR": "548894", "opening_hours": "09:30-23:45; Jun 21-Sep 2: 09:00-00:45; Jul 14,Jul 15 off", "building:shape": "pyramidal", "ref:FR:FANTOIR": "75107P320D", "building:colour": "#706550", "historic:period": "modern", "tourism:visitors": "7000000", "building:material": "iron", "heritage:operator": "mhs", "wikimedia_commons": "Category:Eiffel Tower", "tower:construction": "lattice", "communication:radio": "fm", "mhs:inscription_date": "1964-06-24", "communication:television": "dvb-t"},"boundingbox":["48.8574753","48.8590453","2.2933119","2.2956897"]},{"place_id":89203605,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright","osm_type":"node","osm_id":3135278479,"lat":"48.8581328","lon":"2.2944968","category":"amenity","type":"restaurant","place_rank":30,"importance":0.2917175836992075,"addresstype":"amenity","name":"Le Jules Verne","display_name":"Le Jules Verne, Avenue Gustave Eiffel, Quartier du Gros-Caillou, Paris 7e Arrondissement, Paris, Île-de-France, France métropolitaine, 75007, France","address":{"amenity":"Le Jules Verne","road":"Avenue Gustave Eiffel","city_block":"Quartier du Gros-Caillou","suburb":"Paris 7e Arrondissement","city_district":"Paris","city":"Paris","ISO3166-2-lvl6":"FR-75C","state":"Île-de-France","ISO3166-2-lvl4":"FR-IDF","region":"France métropolitaine","postcode":"75007","country":"France","country_code":"fr"},"extratags":{"level": "2", "stars": "1", "cuisine": "french", "website": "https://www.lejulesverne-paris.com", "wikidata": "Q3223818", "check_date": "2025-10-23", "wheelchair": "yes", "indoor_seating": "no", "outdoor_seating": "yes"},"boundingbox":["48.8580828","48.8581828","2.2944468","2.2945468"]}]', ['response_headers' => ['content-type' => 'application/json']]); } self::fail(sprintf('Unexpected http call "%s %s".', $method, $url)); diff --git a/tests/Mapping/Driver/AttributeDriverTest.php b/tests/Mapping/Driver/AttributeDriverTest.php index 2e3d7c1..00890dd 100644 --- a/tests/Mapping/Driver/AttributeDriverTest.php +++ b/tests/Mapping/Driver/AttributeDriverTest.php @@ -42,6 +42,26 @@ public function testLoadMetadata(): void self::assertSame('latitude', $metadata->latitudeProperty->getName()); self::assertNotNull($metadata->longitudeProperty); self::assertSame('longitude', $metadata->longitudeProperty->getName()); + self::assertNotNull($metadata->northProperty); + self::assertSame('north', $metadata->northProperty->getName()); + self::assertNotNull($metadata->southProperty); + self::assertSame('south', $metadata->southProperty->getName()); + self::assertNotNull($metadata->eastProperty); + self::assertSame('east', $metadata->eastProperty->getName()); + self::assertNotNull($metadata->westProperty); + self::assertSame('west', $metadata->westProperty->getName()); + self::assertNotNull($metadata->streetNumberProperty); + self::assertSame('streetNumber', $metadata->streetNumberProperty->getName()); + self::assertNotNull($metadata->streetNameProperty); + self::assertSame('streetName', $metadata->streetNameProperty->getName()); + self::assertNotNull($metadata->localityProperty); + self::assertSame('locality', $metadata->localityProperty->getName()); + self::assertNotNull($metadata->postalCodeProperty); + self::assertSame('postalCode', $metadata->postalCodeProperty->getName()); + self::assertNotNull($metadata->subLocalityProperty); + self::assertSame('subLocality', $metadata->subLocalityProperty->getName()); + self::assertNotNull($metadata->countryProperty); + self::assertSame('country', $metadata->countryProperty->getName()); } public function testLoadMetadataWithAddressGetter(): void diff --git a/tests/Mapping/Driver/Fixtures/Dummy.php b/tests/Mapping/Driver/Fixtures/Dummy.php index aa70eed..c76c798 100644 --- a/tests/Mapping/Driver/Fixtures/Dummy.php +++ b/tests/Mapping/Driver/Fixtures/Dummy.php @@ -13,9 +13,19 @@ namespace Bazinga\GeocoderBundle\Tests\Mapping\Driver\Fixtures; use Bazinga\GeocoderBundle\Mapping\Attributes\Address; +use Bazinga\GeocoderBundle\Mapping\Attributes\Country; +use Bazinga\GeocoderBundle\Mapping\Attributes\East; use Bazinga\GeocoderBundle\Mapping\Attributes\Geocodeable; use Bazinga\GeocoderBundle\Mapping\Attributes\Latitude; +use Bazinga\GeocoderBundle\Mapping\Attributes\Locality; use Bazinga\GeocoderBundle\Mapping\Attributes\Longitude; +use Bazinga\GeocoderBundle\Mapping\Attributes\North; +use Bazinga\GeocoderBundle\Mapping\Attributes\PostalCode; +use Bazinga\GeocoderBundle\Mapping\Attributes\South; +use Bazinga\GeocoderBundle\Mapping\Attributes\StreetName; +use Bazinga\GeocoderBundle\Mapping\Attributes\StreetNumber; +use Bazinga\GeocoderBundle\Mapping\Attributes\SubLocality; +use Bazinga\GeocoderBundle\Mapping\Attributes\West; #[Geocodeable(provider: 'acme')] final class Dummy @@ -28,4 +38,34 @@ final class Dummy #[Address] public ?string $address; + + #[North] + public ?float $north; + + #[South] + public ?float $south; + + #[East] + public ?float $east; + + #[West] + public ?float $west; + + #[StreetNumber] + public int|string|null $streetNumber; + + #[StreetName] + public ?string $streetName; + + #[Locality] + public ?string $locality; + + #[PostalCode] + public ?string $postalCode; + + #[SubLocality] + public ?string $subLocality; + + #[Country] + public ?string $country; }