-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added IP2Location and IP2LocationBinary provider. (#1031)
* Added IP2Location and IP2LocationBinary provider. * Fixed spacing issues. * Replaced tabs into spaces. * Update src/Provider/IP2Location/IP2Location.php Co-Authored-By: atymic <atymicq@gmail.com> * Updated codes and format to match Geocoder standards and requirements. * Added IP2Location API configuration. * Updated indent and formatting issues. * Updated Readme.md. * Updated Readme.md to explain IP2Location Web service credit usage. * Update Readme.md
- Loading branch information
0 parents
commit e71fd5b
Showing
14 changed files
with
478 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.gitattributes export-ignore | ||
.travis.yml export-ignore | ||
phpunit.xml.dist export-ignore | ||
Tests/ export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
vendor/ | ||
composer.lock | ||
phpunit.xml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
language: php | ||
sudo: false | ||
|
||
php: 7.2 | ||
|
||
|
||
install: | ||
- composer update --prefer-stable --prefer-dist | ||
|
||
script: | ||
- composer test-ci | ||
|
||
after_success: | ||
- wget https://scrutinizer-ci.com/ocular.phar | ||
- php ocular.phar code-coverage:upload --format=php-clover build/coverage.xml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Geocoder package. | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* | ||
* @license MIT License | ||
*/ | ||
|
||
namespace Geocoder\Provider\IP2Location; | ||
|
||
use Geocoder\Exception\InvalidCredentials; | ||
use Geocoder\Exception\UnsupportedOperation; | ||
use Geocoder\Collection; | ||
use Geocoder\Model\Address; | ||
use Geocoder\Model\AddressCollection; | ||
use Geocoder\Query\GeocodeQuery; | ||
use Geocoder\Query\ReverseQuery; | ||
use Geocoder\Http\Provider\AbstractHttpProvider; | ||
use Geocoder\Provider\Provider; | ||
use Http\Client\HttpClient; | ||
|
||
/** | ||
* @author William Durand <william.durand1@gmail.com> | ||
*/ | ||
final class IP2Location extends AbstractHttpProvider implements Provider | ||
{ | ||
/** | ||
* @var string | ||
*/ | ||
const ENDPOINT_URL = 'https://api.ip2location.com/v2/?key=%s&ip=%s&format=json&package=WS9'; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $apiKey; | ||
|
||
/** | ||
* @var string | ||
*/ | ||
private $endpointUrl; | ||
|
||
/** | ||
* @param HttpClient $client a HTTP adapter | ||
* @param string $apiKey an API key | ||
*/ | ||
public function __construct(HttpClient $client, string $apiKey) | ||
{ | ||
parent::__construct($client); | ||
|
||
$this->apiKey = $apiKey; | ||
$this->endpointUrl = self::ENDPOINT_URL; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function geocodeQuery(GeocodeQuery $query): Collection | ||
{ | ||
$address = $query->getText(); | ||
|
||
if (empty($this->apiKey)) { | ||
throw new InvalidCredentials('No API key provided.'); | ||
} | ||
|
||
if (!filter_var($address, FILTER_VALIDATE_IP)) { | ||
throw new UnsupportedOperation('The IP2Location provider does not support street addresses, only IP addresses.'); | ||
} | ||
|
||
if (in_array($address, ['127.0.0.1', '::1'])) { | ||
return new AddressCollection([$this->getLocationForLocalhost()]); | ||
} | ||
|
||
$url = sprintf($this->endpointUrl, $this->apiKey, $address); | ||
|
||
return $this->executeQuery($url); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function reverseQuery(ReverseQuery $query): Collection | ||
{ | ||
throw new UnsupportedOperation('The IP2Location provider is not able to do reverse geocoding.'); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getName(): string | ||
{ | ||
return 'ip2location'; | ||
} | ||
|
||
/** | ||
* @param string $url | ||
* | ||
* @return Collection | ||
*/ | ||
private function executeQuery(string $url): AddressCollection | ||
{ | ||
$content = $this->getUrlContents($url); | ||
$data = json_decode($content, true); | ||
|
||
if (empty($data)) { | ||
return new AddressCollection([]); | ||
} | ||
|
||
if (isset($data['response'])) { | ||
if (preg_match('/suspended|denied|invalid account/i', $data['response'])) { | ||
throw new InvalidCredentials('API Key provided is not valid.'); | ||
} elseif (preg_match('/insufficient/i', $data['response'])) { | ||
throw new InvalidCredentials('Insufficient credits to use IP2Location service.'); | ||
} elseif (preg_match('/invalid ip address/i', $data['response'])) { | ||
throw new UnsupportedOperation('Invalid IP address.'); | ||
} else { | ||
throw new UnsupportedOperation('Unexpected error.'); | ||
} | ||
} | ||
|
||
if (isset($data['region_name'])) { | ||
$adminLevels = [[ | ||
'name' => $data['region_name'], | ||
'level' => 1, | ||
]]; | ||
} else { | ||
$adminLevels = []; | ||
} | ||
|
||
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' => $adminLevels, | ||
'country' => $data['country_name'] ?? null, | ||
'countryCode' => $data['country_code'] ?? null, | ||
]), | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2011 — William Durand <william.durand1@gmail.com> | ||
|
||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# IP2Location Geocoder provider | ||
[![Build Status](https://travis-ci.org/geocoder-php/ip2location-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/ip2location-provider) | ||
[![Latest Stable Version](https://poser.pugx.org/geocoder-php/ip2location-provider/v/stable)](https://packagist.org/packages/geocoder-php/ip2location-provider) | ||
[![Total Downloads](https://poser.pugx.org/geocoder-php/ip2location-provider/downloads)](https://packagist.org/packages/geocoder-php/ip2location-provider) | ||
[![Monthly Downloads](https://poser.pugx.org/geocoder-php/ip2location-provider/d/monthly.png)](https://packagist.org/packages/geocoder-php/ip2location-provider) | ||
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/geocoder-php/ip2location-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ip2location-provider) | ||
[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/ip2location-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ip2location-provider) | ||
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE) | ||
|
||
This is the IP2Location 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-provider | ||
``` | ||
|
||
### Note | ||
|
||
This provider requires IP2Location™ [IP Geolocation Web Service](https://www.ip2location.com/web-service/ip2location) subscription. It is a paid solution with high accuracy. For free solution, please use our free [IpInfoDB](https://github.com/geocoder-php/Geocoder#ip) project. Ipinfodb is using [IP2Location LITE](https://lite.ip2location.com/) database which has less accuracy at city level. | ||
|
||
Please note that this provider is querying IP2Location Web Service **WS9** package and each query will cost **4 credits**. | ||
|
||
### 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). |
Empty file.
1 change: 1 addition & 0 deletions
1
Tests/.cached_responses/api.ip2location.com_1117d6d7b84416500ce339acc9c387700fe81440
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
s:183:"{"country_code":"US","country_name":"United States","region_name":"Oklahoma","city_name":"Tulsa","latitude":"36.15398","longitude":"-95.99278","zip_code":"74101","credits_consumed":4}"; |
1 change: 1 addition & 0 deletions
1
Tests/.cached_responses/api.ip2location.com_6374ec39c79ddd96577dd81a01c013eb573f5b40
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
s:183:"{"country_code":"US","country_name":"United States","region_name":"Oklahoma","city_name":"Tulsa","latitude":"36.15398","longitude":"-95.99278","zip_code":"74101","credits_consumed":4}"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Geocoder package. | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
* | ||
* @license MIT License | ||
*/ | ||
|
||
namespace Geocoder\Provider\IP2Location\Tests; | ||
|
||
use Geocoder\IntegrationTest\BaseTestCase; | ||
use Geocoder\Location; | ||
use Geocoder\Query\GeocodeQuery; | ||
use Geocoder\Query\ReverseQuery; | ||
use Geocoder\Provider\IP2Location\IP2Location; | ||
|
||
class IP2LocationTest extends BaseTestCase | ||
{ | ||
protected function getCacheDir() | ||
{ | ||
return __DIR__.'/.cached_responses'; | ||
} | ||
|
||
public function testGetName() | ||
{ | ||
$provider = new IP2Location($this->getMockedHttpClient(), 'api_key'); | ||
$this->assertEquals('ip2location', $provider->getName()); | ||
} | ||
|
||
/** | ||
* @expectedException \Geocoder\Exception\UnsupportedOperation | ||
* @expectedExceptionMessage The IP2Location provider does not support street addresses, only IP addresses. | ||
*/ | ||
public function testGeocodeWithRandomString() | ||
{ | ||
$provider = new IP2Location($this->getMockedHttpClient(), 'api_key'); | ||
$provider->geocodeQuery(GeocodeQuery::create('foobar')); | ||
} | ||
|
||
/** | ||
* @expectedException \Geocoder\Exception\UnsupportedOperation | ||
* @expectedExceptionMessage The IP2Location provider does not support street addresses, only IP addresses. | ||
*/ | ||
public function testGeocodeWithAddress() | ||
{ | ||
$provider = new IP2Location($this->getMockedHttpClient(), 'api_key'); | ||
$provider->geocodeQuery(GeocodeQuery::create('10 avenue Gambetta, Paris, France')); | ||
} | ||
|
||
/** | ||
* @expectedException \Geocoder\Exception\InvalidCredentials | ||
* @expectedExceptionMessage API Key provided is not valid. | ||
*/ | ||
public function testGeocodeWithInvalidKey() | ||
{ | ||
$provider = new IP2Location($this->getHttpClient('invalid_key'), 'api_key'); | ||
$results = $provider->geocodeQuery(GeocodeQuery::create('74.125.45.100')); | ||
} | ||
|
||
/** | ||
* @expectedException \Geocoder\Exception\UnsupportedOperation | ||
* @expectedExceptionMessage The IP2Location provider does not support street addresses, only IP addresses. | ||
*/ | ||
public function testGeocodeWithInvalidIPAddress() | ||
{ | ||
$provider = new IP2Location($this->getMockedHttpClient(), 'api_key'); | ||
$provider->geocodeQuery(GeocodeQuery::create('300.23.255.5')); | ||
} | ||
|
||
public function testGeocodeWithRealIPv4() | ||
{ | ||
if (!isset($_SERVER['IP2LOCATION_API_KEY'])) { | ||
$this->markTestSkipped('You need to configure the IP2LOCATION_API_KEY value in phpunit.xml'); | ||
} | ||
|
||
$provider = new IP2Location($this->getHttpClient($_SERVER['IP2LOCATION_API_KEY']), $_SERVER['IP2LOCATION_API_KEY']); | ||
$results = $provider->geocodeQuery(GeocodeQuery::create('74.125.45.100')); | ||
|
||
$this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); | ||
$this->assertCount(1, $results); | ||
|
||
/** @var Location $result */ | ||
$result = $results->first(); | ||
$this->assertInstanceOf('\Geocoder\Model\Address', $result); | ||
$this->assertEquals(36.154, $result->getCoordinates()->getLatitude(), '', 0.001); | ||
$this->assertEquals(-95.9928, $result->getCoordinates()->getLongitude(), '', 0.001); | ||
$this->assertEquals(74101, $result->getPostalCode()); | ||
$this->assertEquals('Tulsa', $result->getLocality()); | ||
$this->assertCount(1, $result->getAdminLevels()); | ||
$this->assertEquals('Oklahoma', $result->getAdminLevels()->get(1)->getName()); | ||
$this->assertEquals('United States', $result->getCountry()->getName()); | ||
$this->assertEquals('US', $result->getCountry()->getCode()); | ||
} | ||
|
||
public function testGeocodeWithRealIPv6() | ||
{ | ||
if (!isset($_SERVER['IP2LOCATION_API_KEY'])) { | ||
$this->markTestSkipped('You need to configure the IP2LOCATION_API_KEY value in phpunit.xml'); | ||
} | ||
|
||
$provider = new IP2Location($this->getHttpClient($_SERVER['IP2LOCATION_API_KEY']), $_SERVER['IP2LOCATION_API_KEY']); | ||
$results = $provider->geocodeQuery(GeocodeQuery::create('::ffff:74.125.45.100')); | ||
|
||
$this->assertInstanceOf('Geocoder\Model\AddressCollection', $results); | ||
$this->assertCount(1, $results); | ||
|
||
/** @var Location $result */ | ||
$result = $results->first(); | ||
$this->assertInstanceOf('\Geocoder\Model\Address', $result); | ||
$this->assertEquals(36.154, $result->getCoordinates()->getLatitude(), '', 0.001); | ||
$this->assertEquals(-95.9928, $result->getCoordinates()->getLongitude(), '', 0.001); | ||
$this->assertEquals(74101, $result->getPostalCode()); | ||
$this->assertEquals('Tulsa', $result->getLocality()); | ||
$this->assertCount(1, $result->getAdminLevels()); | ||
$this->assertEquals('Oklahoma', $result->getAdminLevels()->get(1)->getName()); | ||
$this->assertEquals('United States', $result->getCountry()->getName()); | ||
$this->assertEquals('US', $result->getCountry()->getCode()); | ||
} | ||
|
||
/** | ||
* @expectedException \Geocoder\Exception\UnsupportedOperation | ||
* @expectedExceptionMessage The IP2Location provider is not able to do reverse geocoding. | ||
*/ | ||
public function testReverse() | ||
{ | ||
$provider = new IP2Location($this->getMockedHttpClient(), 'api_key'); | ||
$provider->reverseQuery(ReverseQuery::fromCoordinates(0, 0)); | ||
} | ||
} |
Oops, something went wrong.