-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathIpdata.php
More file actions
160 lines (134 loc) · 5.43 KB
/
Ipdata.php
File metadata and controls
160 lines (134 loc) · 5.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
<?php
declare(strict_types=1);
namespace Ipdata\ApiClient;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Nyholm\Psr7\Factory\Psr17Factory;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\ResponseInterface;
/**
* A small client to talk with Ipdata.co API.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Ipdata
{
private const DEFAULT_BASE_URL = 'https://api.ipdata.co';
public const EU_BASE_URL = 'https://eu-api.ipdata.co';
/**
* @var string|null
*/
private $apiKey;
/**
* @var ClientInterface
*/
private $httpClient;
/**
* @var RequestFactoryInterface
*/
private $requestFactory;
/**
* @var string
*/
private $baseUrl;
/**
* Get an instance of the API client. Give it an API key, a PSR-18 client and a PSR-17 request factory.
*
* @param ClientInterface|null $httpClient if null, we will try to use php-http/discovery to find an installed client
* @param RequestFactoryInterface|null $requestFactory if null, we will try to use php-http/discovery to find an installed factory
*/
public function __construct(string $apiKey, ClientInterface $httpClient = null, RequestFactoryInterface $requestFactory = null, string $baseUrl = self::DEFAULT_BASE_URL)
{
if (null === $httpClient) {
if (!class_exists(Psr18ClientDiscovery::class)) {
throw new \LogicException(sprintf('You cannot use the "%s" without a PSR-18 HTTP client. Pass a "%s" as first argument to the constructor OR try running "composer require php-http/discovery".', Ipdata::class, ClientInterface::class));
}
try {
$httpClient = Psr18ClientDiscovery::find();
} catch (NotFoundException $e) {
throw new \LogicException('Could not find any installed HTTP clients. Try installing a package for this list: https://packagist.org/providers/psr/http-client-implementation', 0, $e);
}
}
if (null === $requestFactory) {
if (!class_exists(Psr17Factory::class) && !class_exists(Psr17FactoryDiscovery::class)) {
throw new \LogicException(sprintf('You cannot use the "%s" as no PSR-17 request factory have been provided. Try running "composer require nyholm/psr7".', Ipdata::class));
}
try {
$requestFactory = class_exists(Psr17Factory::class) ? new Psr17Factory() : Psr17FactoryDiscovery::findRequestFactory();
} catch (NotFoundException $e) {
throw new \LogicException('Could not find any PSR-17 factories. Try running "composer require nyholm/psr7".', 0, $e);
}
}
$this->httpClient = $httpClient;
$this->apiKey = $apiKey;
$this->requestFactory = $requestFactory;
$this->baseUrl = $baseUrl;
}
/**
* @param array<string> $fields
*
* @throws \Psr\Http\Client\ClientExceptionInterface
*/
public function lookup(string $ip = '', array $fields = []): array
{
$query = [
'api-key' => $this->apiKey,
];
if (!empty($fields)) {
$query['fields'] = implode(',', $fields);
}
$url = $ip !== '' ? sprintf('%s/%s', $this->baseUrl, $ip) : $this->baseUrl;
$request = $this->requestFactory->createRequest('GET', sprintf('%s?%s', $url, http_build_query($query)));
$response = $this->httpClient->sendRequest($request);
return $this->parseResponse($response);
}
/**
* Bulk lookup, requires paid subscription.
*
* @param array<string> $ips
* @param array<string> $fields
*
* @throws \Psr\Http\Client\ClientExceptionInterface
*/
public function bulkLookup(array $ips, array $fields = []): array
{
$query = [
'api-key' => $this->apiKey,
];
if (!empty($fields)) {
$query['fields'] = implode(',', $fields);
}
$request = $this->requestFactory->createRequest('POST', sprintf('%s/bulk?%s', $this->baseUrl, http_build_query($query)));
$request->getBody()->write(json_encode($ips));
$request = $request->withHeader('Content-Type', 'application/json');
$response = $this->httpClient->sendRequest($request);
return $this->parseResponse($response);
}
/**
* @deprecated Use bulkLookup() instead.
*
* @param array<string> $ips
* @param array<string> $fields
*
* @throws \Psr\Http\Client\ClientExceptionInterface
*/
public function buildLookup(array $ips, array $fields = []): array
{
return $this->bulkLookup($ips, $fields);
}
private function parseResponse(ResponseInterface $response): array
{
$body = $response->getBody()->__toString();
if (0 !== strpos($response->getHeaderLine('Content-Type'), 'application/json')) {
throw new \RuntimeException('Cannot convert response to array. Response has Content-Type:'.$response->getHeaderLine('Content-Type'));
}
$content = json_decode($body, true);
if (JSON_ERROR_NONE !== json_last_error()) {
throw new \RuntimeException(sprintf('Error (%d) when trying to json_decode response', json_last_error()));
}
$content['status'] = $response->getStatusCode();
return $content;
}
}