Skip to content

Commit d108775

Browse files
jGielenjbelien
authored andcommitted
Adding provider ipstack (geocoder-php#879)
* adding ipstack as a provider * fixing the styleci errors * forgot to remove a space for styleci * adding cache for phpunit * added locale to the provider * fix test to pass with deps="low"
1 parent 72c9834 commit d108775

19 files changed

+522
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ Provider | Package | Features | Stats
164164
[IpInfoDB](https://github.com/geocoder-php/ip-info-db-provider) | `geocoder-php/ip-info-db-provider` | IPv4 <br> [Website](http://ipinfodb.com/) | [![Latest Stable Version](https://poser.pugx.org/geocoder-php/ip-info-db-provider/v/stable)](https://packagist.org/packages/geocoder-php/ip-info-db-provider) <br>[![Total Downloads](https://poser.pugx.org/geocoder-php/ip-info-db-provider/downloads)](https://packagist.org/packages/geocoder-php/ip-info-db-provider)
165165
[MaxMind](https://github.com/geocoder-php/maxmind-provider) | `geocoder-php/maxmind-provider` | IPv4, IPv6 <br> [Website](https://www.maxmind.com/) | [![Latest Stable Version](https://poser.pugx.org/geocoder-php/maxmind-provider/v/stable)](https://packagist.org/packages/geocoder-php/maxmind-provider) <br>[![Total Downloads](https://poser.pugx.org/geocoder-php/maxmind-provider/downloads)](https://packagist.org/packages/geocoder-php/maxmind-provider)
166166
[MaxMind Binary](https://github.com/geocoder-php/maxmind-binary-provider) | `geocoder-php/maxmind-binary-provider` | IPv4, IPv6 <br> [Website](https://www.maxmind.com/) | [![Latest Stable Version](https://poser.pugx.org/geocoder-php/maxmind-binary-provider/v/stable)](https://packagist.org/packages/geocoder-php/maxmind-binary-provider) <br>[![Total Downloads](https://poser.pugx.org/geocoder-php/maxmind-binary-provider/downloads)](https://packagist.org/packages/geocoder-php/maxmind-binary-provider)
167+
[ipstack](https://github.com/geocoder-php/ipstack-provider) | `geocoder-php/ipstack-provider` | IPv4, IPv6 <br> [Website](https://ipstack.com/) | [![Latest Stable Version](https://poser.pugx.org/geocoder-php/ipstack-provider/v/stable)](https://packagist.org/packages/geocoder-php/ipstack-provider) <br>[![Total Downloads](https://poser.pugx.org/geocoder-php/ipstack-provider/downloads)](https://packagist.org/packages/geocoder-php/ipstack-provider)
167168

168169
#### Other packages
169170

@@ -475,6 +476,7 @@ following lines and add your own API keys:
475476
<!-- <server name="OPENCAGE_API_KEY" value="YOUR_API_KEY" /> -->
476477
<!-- <server name="PICKPOINT_API_KEY" value="YOUR_API_KEY" /> -->
477478
<!-- <server name="LOCATIONIQ_API_KEY" value="YOUR_API_KEY" /> -->
479+
<!-- <server name="IPSTACK_API_KEY" value="YOUR_API_KEY" /> -->
478480
</php>
479481
```
480482

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
<server name="ALGOLIA_APP_ID" value="YOUR_APP_ID" />
3535
<server name="ALGOLIA_API_KEY" value="YOUR_API_KEY" />
3636
<server name="MAPBOX_GEOCODING_KEY" value="YOUR_GEOCODING_KEY" />
37+
<server name="IPSTACK_API_KEY" value="YOUR_API_KEY" />
3738
<!--<server name="MAXMIND_API_KEY" value="YOUR_API_KEY" />-->
3839
</php>
3940

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.gitattributes export-ignore
2+
.travis.yml export-ignore
3+
phpunit.xml.dist export-ignore
4+
Tests/ export-ignore

src/Provider/Ipstack/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
phpunit.xml

src/Provider/Ipstack/.travis.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
language: php
2+
sudo: false
3+
4+
php: 7.0
5+
6+
7+
install:
8+
- composer update --prefer-stable --prefer-dist
9+
10+
script:
11+
- composer test-ci
12+
13+
after_success:
14+
- wget https://scrutinizer-ci.com/ocular.phar
15+
- php ocular.phar code-coverage:upload --format=php-clover build/coverage.xml
16+

src/Provider/Ipstack/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Change Log
2+
3+
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
4+
5+
## 4.0.0
6+
7+
First release of this library.

src/Provider/Ipstack/Ipstack.php

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Geocoder package.
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*
10+
* @license MIT License
11+
*/
12+
13+
namespace Geocoder\Provider\Ipstack;
14+
15+
use Geocoder\Collection;
16+
use Geocoder\Exception\InvalidArgument;
17+
use Geocoder\Exception\InvalidCredentials;
18+
use Geocoder\Exception\QuotaExceeded;
19+
use Geocoder\Exception\UnsupportedOperation;
20+
use Geocoder\Model\Address;
21+
use Geocoder\Model\AddressCollection;
22+
use Geocoder\Query\GeocodeQuery;
23+
use Geocoder\Query\ReverseQuery;
24+
use Geocoder\Http\Provider\AbstractHttpProvider;
25+
use Geocoder\Provider\Provider;
26+
use Http\Client\HttpClient;
27+
28+
/**
29+
* @author Jonas Gielen <gielenjonas@gmail.com>
30+
*/
31+
final class Ipstack extends AbstractHttpProvider implements Provider
32+
{
33+
/**
34+
* @var string
35+
*/
36+
const GEOCODE_ENDPOINT_URL = 'http://api.ipstack.com/%s?access_key=%s';
37+
38+
/**
39+
* @var string
40+
*/
41+
private $apiKey;
42+
43+
/**
44+
* @param HttpClient $client an HTTP adapter
45+
* @param string $apiKey an API key
46+
*/
47+
public function __construct(HttpClient $client, string $apiKey)
48+
{
49+
if (empty($apiKey)) {
50+
throw new InvalidCredentials('No API key provided.');
51+
}
52+
53+
$this->apiKey = $apiKey;
54+
parent::__construct($client);
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
public function geocodeQuery(GeocodeQuery $query): Collection
61+
{
62+
$address = $query->getText();
63+
64+
// This API doesn't handle IPs
65+
if (!filter_var($address, FILTER_VALIDATE_IP)) {
66+
throw new UnsupportedOperation('The Ipstack provider does not support street addresses.');
67+
}
68+
69+
if (in_array($address, ['127.0.0.1', '::1'])) {
70+
return new AddressCollection([$this->getLocationForLocalhost()]);
71+
}
72+
73+
$url = sprintf(sprintf(self::GEOCODE_ENDPOINT_URL, $address, $this->apiKey));
74+
75+
if (null !== $query->getLocale()) {
76+
$url = sprintf('%s&language=%s', $url, $query->getLocale());
77+
}
78+
79+
$body = $this->getUrlContents($url);
80+
$data = json_decode($body, true);
81+
82+
// https://ipstack.com/documentation#errors
83+
if (isset($data['error'])) {
84+
switch ($data['error']['code']) {
85+
case 301:
86+
throw new InvalidArgument(
87+
'Invalid request (a required parameter is missing).'
88+
);
89+
case 303:
90+
throw new InvalidArgument(
91+
'Bulk requests are not supported on your plan. Please upgrade your subscription.'
92+
);
93+
case 104:
94+
throw new QuotaExceeded(
95+
'The maximum allowed amount of monthly API requests has been reached.'
96+
);
97+
case 101:
98+
throw new InvalidCredentials(
99+
'No API Key was specified or an invalid API Key was specified.'
100+
);
101+
}
102+
}
103+
104+
if (null === $data['latitude']
105+
&& null === $data['longitude']
106+
&& null === $data['city']
107+
&& null === $data['zip']
108+
&& null === $data['country_name']
109+
&& null === $data['country_code']) {
110+
return new AddressCollection([]);
111+
}
112+
113+
$locations[] = Address::createFromArray([
114+
'providedBy' => $this->getName(),
115+
'latitude' => $data['latitude'] ?: null,
116+
'longitude' => $data['longitude'] ?: null,
117+
'locality' => $data['city'] ?: null,
118+
'postalCode' => $data['zip'] ?: null,
119+
'country' => $data['country_name'] ?: null,
120+
'countryCode' => $data['country_code'] ?: null,
121+
]);
122+
123+
return new AddressCollection($locations);
124+
}
125+
126+
/**
127+
* {@inheritdoc}
128+
*/
129+
public function reverseQuery(ReverseQuery $query): Collection
130+
{
131+
throw new UnsupportedOperation('The Ipstack provider is not able to do reverse geocoding.');
132+
}
133+
134+
/**
135+
* {@inheritdoc}
136+
*/
137+
public function getName(): string
138+
{
139+
return 'ipstack';
140+
}
141+
}

src/Provider/Ipstack/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2011 — William Durand <william.durand1@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

src/Provider/Ipstack/Readme.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Ipstack Geocoder provider
2+
[![Build Status](https://travis-ci.org/geocoder-php/ipstack-provider.svg?branch=master)](http://travis-ci.org/geocoder-php/ipstack-provider)
3+
[![Latest Stable Version](https://poser.pugx.org/geocoder-php/ipstack-provider/v/stable)](https://packagist.org/packages/geocoder-php/ipstack-provider)
4+
[![Total Downloads](https://poser.pugx.org/geocoder-php/ipstack-provider/downloads)](https://packagist.org/packages/geocoder-php/ipstack-provider)
5+
[![Monthly Downloads](https://poser.pugx.org/geocoder-php/ipstack-provider/d/monthly.png)](https://packagist.org/packages/geocoder-php/ipstack-provider)
6+
[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/geocoder-php/ipstack-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ipstack-provider)
7+
[![Quality Score](https://img.shields.io/scrutinizer/g/geocoder-php/ipstack-provider.svg?style=flat-square)](https://scrutinizer-ci.com/g/geocoder-php/ipstack-provider)
8+
[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE)
9+
10+
This is the Ipstack provider from the PHP Geocoder. This is a **READ ONLY** repository. See the
11+
[main repo](https://github.com/geocoder-php/Geocoder) for information and documentation.
12+
13+
### Install
14+
15+
```bash
16+
composer require geocoder-php/ipstack-provider
17+
```
18+
19+
### Note
20+
21+
The default language-locale is `en`, you can choose between `de`, `es`, `fr`,
22+
`ja`, `pt-br`, `ru` `zh`.
23+
24+
### Contribute
25+
26+
Contributions are very welcome! Send a pull request to the [main repository](https://github.com/geocoder-php/Geocoder) or
27+
report any issues you find on the [issue tracker](https://github.com/geocoder-php/Geocoder/issues).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
s:417:"{"ip":"2001:0db8:0000:0042:0000:8a2e:0370:7334","type":"ipv6","continent_code":null,"continent_name":null,"country_code":null,"country_name":null,"region_code":null,"region_name":null,"city":null,"zip":null,"latitude":null,"longitude":null,"location":{"geoname_id":null,"capital":null,"languages":null,"country_flag":null,"country_flag_emoji":null,"country_flag_emoji_unicode":null,"calling_code":null,"is_eu":false}}";

0 commit comments

Comments
 (0)