Skip to content

Commit

Permalink
Add support for IP Stack
Browse files Browse the repository at this point in the history
  • Loading branch information
Niek Pijp committed Apr 12, 2022
1 parent 3796026 commit 3bb59f4
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 3 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ return [
'base_url' => env('IP_REGISTRY_URL', 'https://api.ipregistry.co'),
'key' => env('IP_REGISTRY_KEY'),
],
'ip-stack' => [ // Credentials for the ip stack API
'base_url' => env('IP_STACK_URL', 'https://api.ipstack.com'),
'key' => env('IP_STACK_KEY'),
],
'cache_ttl' => DateInterval::createFromDateString('2 months'), // Cache TTL for the geocoder services.
];
```
Expand All @@ -42,12 +46,15 @@ return [
Configure the package with the config file. After that the package can be used like this.

```php
UnlimitedGeolocation::getGeolocation($request)?->countryCode
$location = UnlimitedGeolocation::getGeolocation($request);

// { countryCode: "NL", timeZone: "Europe/Amsterdam" }
````

## Supported services
- [Cloudflare IP geolocation](https://support.cloudflare.com/hc/en-us/articles/200168236-Configuring-Cloudflare-IP-Geolocation)
- [IP Registry](https://ipregistry.co/)
- [ipregistry](https://ipregistry.co/)
- [ipstack](https://ipstack.com)

## Contributing
You can add a geocoder by creating a class in the `src/GeoLocators` folder that implements `GeoLocatorContract`.
Expand Down
4 changes: 4 additions & 0 deletions config/unlimited-geolocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@
'base_url' => env('IP_REGISTRY_URL', 'https://api.ipregistry.co'),
'key' => env('IP_REGISTRY_KEY'),
],
'ip-stack' => [
'base_url' => env('IP_STACK_URL', 'https://api.ipstack.com'),
'key' => env('IP_STACK_KEY'),
],
'cache_ttl' => DateInterval::createFromDateString('2 months'),
];
1 change: 1 addition & 0 deletions src/GeoLocators/GeoLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
enum GeoLocator
{
case IpRegistry;
case IpStack;
}
1 change: 1 addition & 0 deletions src/GeoLocators/GeoLocatorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public static function getHandler(GeoLocator $geoLocator): GeoLocatorContract
{
$service = match ($geoLocator) {
GeoLocator::IpRegistry => IpRegistry::class,
GeoLocator::IpStack => IpStack::class,
};

try {
Expand Down
42 changes: 42 additions & 0 deletions src/GeoLocators/IpStack.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Brainstud\UnlimitedGeolocation\GeoLocators;

use Brainstud\UnlimitedGeolocation\Geolocation;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

/**
* Implementation of the IpStack geo-locator.
*/
class IpStack implements GeoLocatorContract
{
private Client $client;

public function __construct()
{
$this->client = new Client();
}

public function getGeolocation(string $ip): ?Geolocation
{
if (! ($baseUrl = config('unlimited-geolocation.ip-stack.base_url'))
|| ! ($apiKey = config('unlimited-geolocation.ip-stack.key'))
) {
return null;
}

try {
$res = $this->client->request('GET', "$baseUrl/$ip?access_key=$apiKey");
$data = json_decode($res->getBody()->getContents());

return Geolocation::fromIpStack($data);
} catch (RequestException $e) {
if ($e->hasResponse() && $e->getResponse()->getStatusCode() === 400) {
return null;
}

throw $e;
}
}
}
15 changes: 14 additions & 1 deletion src/Geolocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,20 @@ public static function fromCountryCode(string $countryCode): Geolocation
public static function fromIpRegistry(stdClass $data): Geolocation
{
$countryCode = $data->location?->country?->code;
$timeZone = $data->time_zone?->id;
$timeZone = property_exists($data, 'time_zone') ? $data->time_zone?->id : null;

return new Geolocation($countryCode, $timeZone);
}

/**
* Convert IpRegistry data to Geolocation
* @param stdClass $data
* @return Geolocation
*/
public static function fromIpStack(stdClass $data): Geolocation
{
$countryCode = $data->country_code;
$timeZone = property_exists($data, 'time_zone') ? $data->time_zone?->id : null;

return new Geolocation($countryCode, $timeZone);
}
Expand Down

0 comments on commit 3bb59f4

Please sign in to comment.