diff --git a/src/Provider/IP2LocationIo/.gitattributes b/src/Provider/IP2LocationIo/.gitattributes new file mode 100644 index 000000000..d04504afd --- /dev/null +++ b/src/Provider/IP2LocationIo/.gitattributes @@ -0,0 +1,4 @@ +.gitattributes export-ignore +.travis.yml export-ignore +phpunit.xml.dist export-ignore +Tests/ export-ignore diff --git a/src/Provider/IP2LocationIo/.github/workflows/provider.yml b/src/Provider/IP2LocationIo/.github/workflows/provider.yml new file mode 100644 index 000000000..d7fbb64c2 --- /dev/null +++ b/src/Provider/IP2LocationIo/.github/workflows/provider.yml @@ -0,0 +1,33 @@ +name: Provider + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + name: PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-version: ['8.0', '8.1', '8.2'] + steps: + - uses: actions/checkout@v3 + - name: Use PHP ${{ matrix.php-version }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: curl + - name: Validate composer.json and composer.lock + run: composer validate --strict + - name: Install dependencies + run: composer update --prefer-stable --prefer-dist --no-progress + - name: Run test suite + run: composer run-script test-ci + - name: Upload Coverage report + run: | + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover build/coverage.xml diff --git a/src/Provider/IP2LocationIo/.gitignore b/src/Provider/IP2LocationIo/.gitignore new file mode 100644 index 000000000..c49a5d8df --- /dev/null +++ b/src/Provider/IP2LocationIo/.gitignore @@ -0,0 +1,3 @@ +vendor/ +composer.lock +phpunit.xml diff --git a/src/Provider/IP2LocationIo/CHANGELOG.md b/src/Provider/IP2LocationIo/CHANGELOG.md new file mode 100644 index 000000000..746b7151f --- /dev/null +++ b/src/Provider/IP2LocationIo/CHANGELOG.md @@ -0,0 +1,7 @@ +# Change Log + +The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release. + +## 1.0.0 + +First release of this library. diff --git a/src/Provider/IP2LocationIo/IP2LocationIo.php b/src/Provider/IP2LocationIo/IP2LocationIo.php new file mode 100644 index 000000000..654577878 --- /dev/null +++ b/src/Provider/IP2LocationIo/IP2LocationIo.php @@ -0,0 +1,118 @@ + + */ +final class IP2LocationIo extends AbstractHttpProvider implements Provider +{ + /** + * @var string + */ + public const ENDPOINT_URL = 'https://api.ip2location.io/?key=%s&ip=%s'; + + /** + * @var string + */ + private $apiKey; + + /** + * @var string + */ + private $endpointUrl; + + /** + * @param ClientInterface $client an HTTP adapter + * @param string $apiKey an API key + * + * @throws \Geocoder\Exception\InvalidArgument + */ + public function __construct(ClientInterface $client, string $apiKey) + { + parent::__construct($client); + + $this->apiKey = $apiKey; + } + + public function geocodeQuery(GeocodeQuery $query): Collection + { + $address = $query->getText(); + if ($this->apiKey === null) { + throw new InvalidCredentials('No API Key provided.'); + } + + if (!filter_var($address, FILTER_VALIDATE_IP)) { + throw new UnsupportedOperation('The IP2LocationIo provider does not support street addresses, only IPv4 or IPv6 addresses.'); + } + + if ($address === '127.0.0.1') { + return new AddressCollection([$this->getLocationForLocalhost()]); + } + + $url = sprintf(self::ENDPOINT_URL, $this->apiKey, $address); + + return $this->executeQuery($url); + } + + public function reverseQuery(ReverseQuery $query): Collection + { + throw new UnsupportedOperation('The IP2LocationIo provider is not able to do reverse geocoding.'); + } + + public function getName(): string + { + return 'ip2location_io'; + } + + private function executeQuery(string $url): AddressCollection + { + $content = $this->getUrlContents($url); + $data = json_decode($content, true); + + if (empty($data) || isset($data['error'])) { + return new AddressCollection([]); + } + + $timeZone = timezone_name_from_abbr('', (int) substr($data['time_zone'], 0, strpos($data['time_zone'], ':')) * 3600, 0); + + if (isset($data['time_zone_info']['olson'])) { + $timeZone = $data['time_zone_info']['olson']; + } + + return new AddressCollection([ + Address::createFromArray([ + 'providedBy' => $this->getName(), + 'latitude' => $data['latitude'] ?? null, + 'longitude' => $data['longitude'] ?? null, + 'locality' => $data['city_name'] ?? null, + 'postalCode' => $data['zip_code'] ?? null, + 'adminLevels' => [['name' => $data['region_name'], 'level' => 1]], + 'country' => $data['country_name'] ?? null, + 'countryCode' => $data['country_code'] ?? null, + 'timezone' => $timeZone, + ]), + ]); + } +} diff --git a/src/Provider/IP2LocationIo/LICENSE b/src/Provider/IP2LocationIo/LICENSE new file mode 100644 index 000000000..2ac7905bb --- /dev/null +++ b/src/Provider/IP2LocationIo/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 — IP2Location + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/src/Provider/IP2LocationIo/Readme.md b/src/Provider/IP2LocationIo/Readme.md new file mode 100644 index 000000000..fd698ade6 --- /dev/null +++ b/src/Provider/IP2LocationIo/Readme.md @@ -0,0 +1,26 @@ +# IP2LocationIo Geocoder provider +[![Build Status](https://travis-ci.org/geocoder-php/ip2location-io-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/ip2location-io-provider) +[![Latest Stable Version](https://poser.pugx.org/geocoder-php/ip2location-io-provider/v/stable)](https://packagist.org/packages/geocoder-php/ip2location-io-provider) +[![Total Downloads](https://poser.pugx.org/geocoder-php/ip2location-io-provider/downloads)](https://packagist.org/packages/geocoder-php/ip2location-io-provider) +[![Monthly Downloads](https://poser.pugx.org/geocoder-php/ip2location-io-provider/d/monthly.png)](https://packagist.org/packages/geocoder-php/ip2location-io-provider) +[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/geocoder-php/ip2location-io-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ip2location-io-provider) +[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/ip2location-io-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ip2location-io-provider) +[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) + +This is the IP2LocationIo provider from the PHP Geocoder. This is a **READ ONLY** repository. See the +[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation. + +### Install + +```bash +composer require geocoder-php/ip2location-io-provider +``` + +### Note + +This provider requires IP2Location.io [IP Geolocation Web Service](https://www.ip2location.io) subscription. It offers free & paid solution with high accuracy. + +### Contribute + +Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or +report any issues you find on the [issue tracker](https://github.com/geocoder-php/Geocoder/issues). diff --git a/src/Provider/IP2LocationIo/Tests/.cached_responses/.gitkeep b/src/Provider/IP2LocationIo/Tests/.cached_responses/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_1664337cf047d848527cad7af25777f91c27bdcb b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_1664337cf047d848527cad7af25777f91c27bdcb new file mode 100644 index 000000000..6a8b0086b --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_1664337cf047d848527cad7af25777f91c27bdcb @@ -0,0 +1 @@ +s:1799:"{"ip":"2001:4860:4860:0000:0000:0000:0000:8888","country_code":"US","country_name":"United States of America","region_name":"California","city_name":"Mountain View","latitude":37.38605,"longitude":-122.08385,"zip_code":"94041","time_zone":"-07:00","asn":"15169","as":"Google LLC","isp":"Google LLC","domain":"google.com","net_speed":"T1","idd_code":"1","area_code":"650","weather_station_code":"USCA0746","weather_station_name":"Mountain View","mcc":"-","mnc":"-","mobile_brand":"-","elevation":31,"usage_type":"DCH","address_type":"Anycast","continent":{"name":"North America","code":"NA","hemisphere":["north","west"],"translation":{"lang":null,"value":null}},"district":"Santa Clara County","country":{"name":"United States of America","alpha3_code":"USA","numeric_code":840,"demonym":"Americans","flag":"https://cdn.ip2location.io/assets/img/flags/us.png","capital":"Washington, D.C.","total_area":9826675,"population":331002651,"currency":{"code":"USD","name":"United States Dollar","symbol":"$"},"language":{"code":"EN","name":"English"},"tld":"us","translation":{"lang":null,"value":null}},"region":{"name":"California","code":"US-CA","translation":{"lang":"","value":""}},"city":{"name":"Mountain View","translation":{"lang":null,"value":null}},"time_zone_info":{"olson":"America/Los_Angeles","current_time":"2023-10-10T00:24:23-07:00","gmt_offset":-25200,"is_dst":true,"sunrise":"07:11","sunset":"18:38"},"geotargeting":{"metro":"807"},"ads_category":"IAB19-11","ads_category_name":"Data Centers","is_proxy":false,"proxy":{"last_seen":9,"proxy_type":"DCH","threat":"-","provider":"-","is_vpn":false,"is_tor":false,"is_data_center":true,"is_public_proxy":false,"is_web_proxy":false,"is_web_crawler":false,"is_residential_proxy":false,"is_spammer":false,"is_scanner":false,"is_botnet":false}}"; \ No newline at end of file diff --git a/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_615324cf048b3b1595c8137d2556dd5b07aa1a39 b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_615324cf048b3b1595c8137d2556dd5b07aa1a39 new file mode 100644 index 000000000..ad01ae28d --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_615324cf048b3b1595c8137d2556dd5b07aa1a39 @@ -0,0 +1 @@ +s:1739:"{"ip":"83.227.123.8","country_code":"SE","country_name":"Sweden","region_name":"Blekinge lan","city_name":"Karlskrona","latitude":56.16156,"longitude":15.58661,"zip_code":"37193","time_zone":"+02:00","asn":"2119","as":"Telenor Norge AS","isp":"Telenor Sverige AB","domain":"telenor.se","net_speed":"DSL","idd_code":"46","area_code":"0455","weather_station_code":"SWXX0014","weather_station_name":"Karlskrona","mcc":"240","mnc":"06/08","mobile_brand":"Telenor","elevation":16,"usage_type":"ISP/MOB","address_type":"Unicast","continent":{"name":"Europe","code":"EU","hemisphere":["north","east"],"translation":{"lang":null,"value":null}},"district":"Karlskrona Municipality","country":{"name":"Sweden","alpha3_code":"SWE","numeric_code":752,"demonym":"Swedes","flag":"https://cdn.ip2location.io/assets/img/flags/se.png","capital":"Stockholm","total_area":450295,"population":10099265,"currency":{"code":"SEK","name":"Swedish Krona","symbol":"kr"},"language":{"code":"SV","name":"Swedish"},"tld":"se","translation":{"lang":null,"value":null}},"region":{"name":"Blekinge lan","code":"SE-K","translation":{"lang":"","value":""}},"city":{"name":"Karlskrona","translation":{"lang":null,"value":null}},"time_zone_info":{"olson":"Europe/Stockholm","current_time":"2023-10-10T09:24:24+02:00","gmt_offset":7200,"is_dst":true,"sunrise":"07:18","sunset":"18:10"},"geotargeting":{"metro":"-"},"ads_category":"IAB19-18","ads_category_name":"Internet Technology","is_proxy":false,"proxy":{"last_seen":0,"proxy_type":"-","threat":"-","provider":"-","is_vpn":false,"is_tor":false,"is_data_center":false,"is_public_proxy":false,"is_web_proxy":false,"is_web_crawler":false,"is_residential_proxy":false,"is_spammer":false,"is_scanner":false,"is_botnet":false}}"; \ No newline at end of file diff --git a/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_8d0f99f5dfc5918a8ae24885372cced4c5386727 b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_8d0f99f5dfc5918a8ae24885372cced4c5386727 new file mode 100644 index 000000000..d7a9973f5 --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_8d0f99f5dfc5918a8ae24885372cced4c5386727 @@ -0,0 +1 @@ +s:1769:"{"ip":"8.8.8.8","country_code":"US","country_name":"United States of America","region_name":"California","city_name":"Mountain View","latitude":37.405992,"longitude":-122.078515,"zip_code":"94043","time_zone":"-07:00","asn":"15169","as":"Google LLC","isp":"Google LLC","domain":"google.com","net_speed":"T1","idd_code":"1","area_code":"650","weather_station_code":"USCA0746","weather_station_name":"Mountain View","mcc":"-","mnc":"-","mobile_brand":"-","elevation":32,"usage_type":"DCH","address_type":"Anycast","continent":{"name":"North America","code":"NA","hemisphere":["north","west"],"translation":{"lang":null,"value":null}},"district":"Santa Clara County","country":{"name":"United States of America","alpha3_code":"USA","numeric_code":840,"demonym":"Americans","flag":"https://cdn.ip2location.io/assets/img/flags/us.png","capital":"Washington, D.C.","total_area":9826675,"population":331002651,"currency":{"code":"USD","name":"United States Dollar","symbol":"$"},"language":{"code":"EN","name":"English"},"tld":"us","translation":{"lang":null,"value":null}},"region":{"name":"California","code":"US-CA","translation":{"lang":"","value":""}},"city":{"name":"Mountain View","translation":{"lang":null,"value":null}},"time_zone_info":{"olson":"America/Los_Angeles","current_time":"2023-10-10T00:24:23-07:00","gmt_offset":-25200,"is_dst":true,"sunrise":"07:11","sunset":"18:38"},"geotargeting":{"metro":"807"},"ads_category":"IAB19-11","ads_category_name":"Data Centers","is_proxy":false,"proxy":{"last_seen":9,"proxy_type":"DCH","threat":"-","provider":"-","is_vpn":false,"is_tor":false,"is_data_center":true,"is_public_proxy":false,"is_web_proxy":false,"is_web_crawler":false,"is_residential_proxy":false,"is_spammer":false,"is_scanner":false,"is_botnet":false}}"; \ No newline at end of file diff --git a/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_d116b28ff5fec0e2b48febf01ca37ca482438661 b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_d116b28ff5fec0e2b48febf01ca37ca482438661 new file mode 100644 index 000000000..0e7f22dc9 --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/.cached_responses/api.ip2location.io_d116b28ff5fec0e2b48febf01ca37ca482438661 @@ -0,0 +1 @@ +s:1735:"{"ip":"74.125.45.100","country_code":"US","country_name":"United States of America","region_name":"Oklahoma","city_name":"Tulsa","latitude":36.15398,"longitude":-95.99278,"zip_code":"74101","time_zone":"-05:00","asn":"15169","as":"Google LLC","isp":"Google LLC","domain":"google.com","net_speed":"T1","idd_code":"1","area_code":"918","weather_station_code":"USOK0537","weather_station_name":"Tulsa","mcc":"-","mnc":"-","mobile_brand":"-","elevation":218,"usage_type":"DCH","address_type":"Unicast","continent":{"name":"North America","code":"NA","hemisphere":["north","west"],"translation":{"lang":null,"value":null}},"district":"Tulsa County","country":{"name":"United States of America","alpha3_code":"USA","numeric_code":840,"demonym":"Americans","flag":"https://cdn.ip2location.io/assets/img/flags/us.png","capital":"Washington, D.C.","total_area":9826675,"population":331002651,"currency":{"code":"USD","name":"United States Dollar","symbol":"$"},"language":{"code":"EN","name":"English"},"tld":"us","translation":{"lang":null,"value":null}},"region":{"name":"Oklahoma","code":"US-OK","translation":{"lang":"","value":""}},"city":{"name":"Tulsa","translation":{"lang":null,"value":null}},"time_zone_info":{"olson":"America/Chicago","current_time":"2023-10-10T02:24:24-05:00","gmt_offset":-18000,"is_dst":true,"sunrise":"07:26","sunset":"18:55"},"geotargeting":{"metro":"671"},"ads_category":"IAB19-11","ads_category_name":"Data Centers","is_proxy":false,"proxy":{"last_seen":9,"proxy_type":"DCH","threat":"-","provider":"-","is_vpn":false,"is_tor":false,"is_data_center":true,"is_public_proxy":false,"is_web_proxy":false,"is_web_crawler":false,"is_residential_proxy":false,"is_spammer":false,"is_scanner":false,"is_botnet":false}}"; \ No newline at end of file diff --git a/src/Provider/IP2LocationIo/Tests/IP2LocationIoTest.php b/src/Provider/IP2LocationIo/Tests/IP2LocationIoTest.php new file mode 100644 index 000000000..d359cf472 --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/IP2LocationIoTest.php @@ -0,0 +1,149 @@ +getMockedHttpClient(), 'api_key'); + $this->assertEquals('ip2location_io', $provider->getName()); + } + + public function testGeocodeWithRandomString(): void + { + $this->expectException(\Geocoder\Exception\UnsupportedOperation::class); + $this->expectExceptionMessage('The IP2LocationIo provider does not support street addresses, only IPv4 or IPv6 addresses.'); + + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $provider->geocodeQuery(GeocodeQuery::create('foobar')); + } + + public function testGeocodeWithAddress(): void + { + $this->expectException(\Geocoder\Exception\UnsupportedOperation::class); + $this->expectExceptionMessage('The IP2LocationIo provider does not support street addresses, only IPv4 or IPv6 addresses.'); + + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')); + } + + public function testGeocodeWithLocalhostIPv4(): void + { + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $results = $provider->geocodeQuery(GeocodeQuery::create('127.0.0.1')); + + $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); + $this->assertCount(1, $results); + + /** @var Location $result */ + $result = $results->first(); + $this->assertInstanceOf('\Geocoder\Model\Address', $result); + $this->assertNull($result->getCoordinates()); + + $this->assertNull($result->getPostalCode()); + $this->assertNull($result->getTimezone()); + $this->assertEmpty($result->getAdminLevels()); + + $this->assertEquals('localhost', $result->getLocality()); + $this->assertEquals('localhost', $result->getCountry()->getName()); + } + + public function testGeocodeWithRealIPv4GetsNullContent(): void + { + $this->expectException(\Geocoder\Exception\InvalidServerResponse::class); + + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $provider->geocodeQuery(GeocodeQuery::create('74.125.45.100')); + } + + public function testGeocodeWithRealIPv4GetsEmptyContent(): void + { + $this->expectException(\Geocoder\Exception\InvalidServerResponse::class); + + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $provider->geocodeQuery(GeocodeQuery::create('74.125.45.100')); + } + + public function testGeocodeWithRealIPv4(): void + { + if (!isset($_SERVER['IP2LOCATION_IO_API_KEY'])) { + $this->markTestSkipped('You need to configure the IP2LOCATION_IO_API_KEY value in phpunit.xml'); + } + + $provider = new IP2LocationIo($this->getHttpClient($_SERVER['IP2LOCATION_IO_API_KEY']), $_SERVER['IP2LOCATION_IO_API_KEY']); + $results = $provider->geocodeQuery(GeocodeQuery::create('8.8.8.8')); + + $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); + $this->assertCount(1, $results); + + /** @var Location $result */ + $result = $results->first(); + $this->assertInstanceOf('\Geocoder\Model\Address', $result); + $this->assertEqualsWithDelta(37.405992, $result->getCoordinates()->getLatitude(), 0.001); + $this->assertEqualsWithDelta(-122.079, $result->getCoordinates()->getLongitude(), 0.001); + $this->assertEquals(94043, $result->getPostalCode()); + $this->assertEquals('Mountain View', $result->getLocality()); + $this->assertCount(1, $result->getAdminLevels()); + $this->assertEquals('California', $result->getAdminLevels()->get(1)->getName()); + $this->assertEquals('United States of America', $result->getCountry()->getName()); + $this->assertEquals('US', $result->getCountry()->getCode()); + $this->assertEquals('America/Los_Angeles', $result->getTimezone()); + } + + public function testGeocodeWithRealIPv6(): void + { + if (!isset($_SERVER['IP2LOCATION_IO_API_KEY'])) { + $this->markTestSkipped('You need to configure the IP2LOCATION_IO_API_KEY value in phpunit.xml'); + } + + $provider = new IP2LocationIo($this->getHttpClient($_SERVER['IP2LOCATION_IO_API_KEY']), $_SERVER['IP2LOCATION_IO_API_KEY']); + $results = $provider->geocodeQuery(GeocodeQuery::create('2001:4860:4860::8888')); + + $this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); + $this->assertCount(1, $results); + + /** @var Location $result */ + $result = $results->first(); + $this->assertInstanceOf('\Geocoder\Model\Address', $result); + $this->assertEqualsWithDelta(37.38605, $result->getCoordinates()->getLatitude(), 0.001); + $this->assertEqualsWithDelta(-122.08385, $result->getCoordinates()->getLongitude(), 0.001); + $this->assertEquals(94041, $result->getPostalCode()); + $this->assertEquals('Mountain View', $result->getLocality()); + $this->assertCount(1, $result->getAdminLevels()); + $this->assertEquals('California', $result->getAdminLevels()->get(1)->getName()); + $this->assertEquals('United States of America', $result->getCountry()->getName()); + $this->assertEquals('US', $result->getCountry()->getCode()); + $this->assertEquals('America/Los_Angeles', $result->getTimezone()); + } + + public function testReverse(): void + { + $this->expectException(\Geocoder\Exception\UnsupportedOperation::class); + $this->expectExceptionMessage('The IP2LocationIo provider is not able to do reverse geocoding.'); + + $provider = new IP2LocationIo($this->getMockedHttpClient(), 'api_key'); + $provider->reverseQuery(ReverseQuery::fromCoordinates(0, 0)); + } +} diff --git a/src/Provider/IP2LocationIo/Tests/IntegrationTest.php b/src/Provider/IP2LocationIo/Tests/IntegrationTest.php new file mode 100644 index 000000000..f46e0a629 --- /dev/null +++ b/src/Provider/IP2LocationIo/Tests/IntegrationTest.php @@ -0,0 +1,44 @@ + + */ +class IntegrationTest extends ProviderIntegrationTest +{ + protected bool $testAddress = false; + + protected bool $testReverse = false; + + protected bool $testIpv6 = false; + + protected function createProvider(ClientInterface $httpClient) + { + return new IP2LocationIo($httpClient, $this->getApiKey()); + } + + protected function getCacheDir(): string + { + return __DIR__.'/.cached_responses'; + } + + protected function getApiKey(): string + { + return $_SERVER['IP2LOCATION_IO_API_KEY']; + } +} diff --git a/src/Provider/IP2LocationIo/composer.json b/src/Provider/IP2LocationIo/composer.json new file mode 100644 index 000000000..53ea91255 --- /dev/null +++ b/src/Provider/IP2LocationIo/composer.json @@ -0,0 +1,52 @@ +{ + "name": "geocoder-php/ip2location-io-provider", + "type": "library", + "description": "Geocoder IP2LocationIo adapter", + "keywords": [], + "homepage": "http://geocoder-php.org/Geocoder/", + "license": "MIT", + "authors": [ + { + "name": "IP2Location", + "email": "support@ip2location.com" + } + ], + "require": { + "php": "^8.0", + "geocoder-php/common-http": "^4.0", + "willdurand/geocoder": "^4.0" + }, + "provide": { + "geocoder-php/provider-implementation": "1.0" + }, + "require-dev": { + "geocoder-php/provider-integration-tests": "^1.0", + "php-http/curl-client": "^2.2", + "php-http/message": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Geocoder\\Provider\\IP2LocationIo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "test": "vendor/bin/phpunit", + "test-ci": "vendor/bin/phpunit --coverage-text --coverage-clover=build/coverage.xml" + }, + "config": { + "allow-plugins": { + "php-http/discovery": true + } + } +} diff --git a/src/Provider/IP2LocationIo/phpunit.xml.dist b/src/Provider/IP2LocationIo/phpunit.xml.dist new file mode 100644 index 000000000..211510121 --- /dev/null +++ b/src/Provider/IP2LocationIo/phpunit.xml.dist @@ -0,0 +1,21 @@ + + + + + ./ + + + ./Tests + ./vendor + + + + + + + + + ./Tests/ + + +