Skip to content

Commit d933b19

Browse files
authored
Merge pull request #21 from ipinfo/uman/fixes
Various updates & fixes for a v2.0.0
2 parents bde9ce0 + 9cae63a commit d933b19

File tree

11 files changed

+288
-204
lines changed

11 files changed

+288
-204
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
build
22
composer.lock
33
vendor
4+
.phpunit.result.cache

.travis.yml

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@ dist: trusty
22
language: php
33

44
php:
5-
- 7.0
6-
- 7.1
75
- 7.2
86
- 7.3
9-
- hhvm
7+
- 7.4
108

119
# This triggers builds to run on the new TravisCI infrastructure.
1210
# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/
@@ -17,23 +15,9 @@ cache:
1715
directories:
1816
- $HOME/.composer/cache
1917

20-
matrix:
21-
include:
22-
- php: 7.0
23-
env: 'COMPOSER_FLAGS="--prefer-stable --prefer-lowest"'
24-
allow_failures:
25-
- php: hhvm
26-
2718
before_script:
2819
- travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist
2920

3021
script:
3122
- vendor/bin/phpcs --standard=psr2 src/
3223
- vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
33-
34-
after_script:
35-
- |
36-
if [[ "$TRAVIS_PHP_VERSION" != 'hhvm' && "$TRAVIS_PHP_VERSION" = '7.0' ]]; then
37-
wget https://scrutinizer-ci.com/ocular.phar
38-
php ocular.phar code-coverage:upload --format=php-clover coverage.clover
39-
fi

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# CHANGELOG
2+
3+
### 2.0.0 (November 2020)
4+
5+
- A `guzzle_opts` option is supported in the settings, which allows full Guzzle
6+
option overrides.
7+
- A `timeout` option is supported in the settings, which is the request timeout
8+
value, and defaults to 2 seconds.
9+
**BREAKING**: this was previously unconfigurable and was 0 seconds,
10+
i.e. infinite timeout.
11+
- The `buildHeaders` method on the main `IPinfo` client is now private.
12+
**BREAKING**: this will no longer be available for use from the client.
13+
- Only non-EOL PHP 7 versions are supported. In particular, PHP 7.2 and above
14+
are all supported and tested in the CI.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,16 @@ It's possible to use a custom cache by creating a child class of the [CacheInter
154154
>>> $client = new IPinfo($access_token, $settings);
155155
```
156156

157+
### Overriding HTTP Client options
158+
159+
The IPinfo client constructor accepts a `timeout` key which is the request
160+
timeout in seconds.
161+
162+
For full flexibility, a `guzzle_opts` key is accepted which accepts an
163+
associative array which is described in [Guzzle Request Options](https://docs.guzzlephp.org/en/stable/request-options.html).
164+
Options set here will override any custom settings set by the IPinfo client
165+
internally in case of conflict, including headers.
166+
157167
### Internationalization
158168

159169
When looking up an IP address, the response object includes a `Details->country_name` attribute which includes the country name based on American English. It is possible to return the country name in other languages by setting the `countries_file` keyword argument when creating the `IPinfo` object.

composer.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
"email": "[email protected]",
1414
"homepage": "https://github.com/jhtimmins",
1515
"role": "Developer"
16+
},
17+
{
18+
"name": "Uman Shahzad",
19+
"email": "[email protected]",
20+
"homepage": "https://github.com/UmanShahzad",
21+
"role": "Developer"
1622
}
1723
],
1824
"require": {
@@ -42,7 +48,7 @@
4248
},
4349
"extra": {
4450
"branch-alias": {
45-
"dev-master": "1.0-dev"
51+
"dev-master": "2.0-dev"
4652
}
4753
},
4854
"config": {

phpunit.xml.dist

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,16 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit bootstrap="vendor/autoload.php"
3-
backupGlobals="false"
4-
backupStaticAttributes="false"
5-
colors="true"
6-
verbose="true"
7-
convertErrorsToExceptions="true"
8-
convertNoticesToExceptions="true"
9-
convertWarningsToExceptions="true"
10-
processIsolation="false"
11-
stopOnFailure="false">
12-
<testsuites>
13-
<testsuite name="ipinfo Test Suite">
14-
<directory>tests</directory>
15-
</testsuite>
16-
</testsuites>
17-
<filter>
18-
<whitelist>
19-
<directory suffix=".php">src/</directory>
20-
</whitelist>
21-
</filter>
22-
<logging>
23-
<log type="tap" target="build/report.tap"/>
24-
<log type="junit" target="build/report.junit.xml"/>
25-
</logging>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php" backupGlobals="false" backupStaticAttributes="false" colors="true" verbose="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" stopOnFailure="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
3+
<coverage>
4+
<include>
5+
<directory suffix=".php">src/</directory>
6+
</include>
7+
</coverage>
8+
<testsuites>
9+
<testsuite name="ipinfo Test Suite">
10+
<directory>tests</directory>
11+
</testsuite>
12+
</testsuites>
13+
<logging>
14+
<junit outputFile="build/report.junit.xml"/>
15+
</logging>
2616
</phpunit>

psalm.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0"?>
2+
<psalm
3+
errorLevel="8"
4+
resolveFromConfigFile="true"
5+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6+
xmlns="https://getpsalm.org/schema/config"
7+
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
8+
>
9+
<projectFiles>
10+
<directory name="src" />
11+
<ignoreFiles>
12+
<directory name="vendor" />
13+
</ignoreFiles>
14+
</projectFiles>
15+
</psalm>

src/IPinfo.php

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class IPinfo
1818
const COUNTRIES_FILE_DEFAULT = __DIR__ . '/countries.json';
1919
const REQUEST_TYPE_GET = 'GET';
2020
const STATUS_CODE_QUOTA_EXCEEDED = 429;
21+
const REQUEST_TIMEOUT_DEFAULT = 2; // seconds
2122

2223
public $access_token;
2324
public $cache;
@@ -27,7 +28,20 @@ class IPinfo
2728
public function __construct($access_token = null, $settings = [])
2829
{
2930
$this->access_token = $access_token;
30-
$this->http_client = new Client(['http_errors' => false]);
31+
32+
/*
33+
Support a timeout first-class, then a `guzzle_opts` key that can
34+
override anything.
35+
*/
36+
$guzzle_opts = [
37+
'http_errors' => false,
38+
'headers' => $this->buildHeaders(),
39+
'timeout' => $settings['timeout'] ?? self::REQUEST_TIMEOUT_DEFAULT
40+
];
41+
if (isset($settings['guzzle_opts'])) {
42+
$guzzle_opts = array_merge($guzzle_opts, $settings['guzzle_opts']);
43+
}
44+
$this->http_client = new Client($guzzle_opts);
3145

3246
$countries_file = $settings['countries_file'] ?? self::COUNTRIES_FILE_DEFAULT;
3347
$this->countries = $this->readCountryNames($countries_file);
@@ -50,7 +64,6 @@ public function __construct($access_token = null, $settings = [])
5064
public function getDetails($ip_address = null)
5165
{
5266
$response_details = $this->getRequestDetails((string) $ip_address);
53-
5467
return $this->formatDetailsObject($response_details);
5568
}
5669

@@ -84,56 +97,57 @@ public function formatDetailsObject($details = [])
8497
*/
8598
public function getRequestDetails(string $ip_address)
8699
{
87-
if (!$this->cache->has($ip_address)) {
88-
$url = self::API_URL;
89-
if ($ip_address) {
90-
$url .= "/$ip_address";
91-
}
92-
93-
try {
94-
$response = $this->http_client->request(
95-
self::REQUEST_TYPE_GET,
96-
$url,
97-
$this->buildHeaders()
98-
);
99-
} catch (GuzzleException $e) {
100-
throw new IPinfoException($e->getMessage());
101-
} catch (Exception $e) {
102-
throw new IPinfoException($e->getMessage());
103-
}
104-
105-
if ($response->getStatusCode() == self::STATUS_CODE_QUOTA_EXCEEDED) {
106-
throw new IPinfoException('IPinfo request quota exceeded.');
107-
} elseif ($response->getStatusCode() >= 400) {
108-
throw new IPinfoException('Exception: ' . json_encode([
100+
if ($this->cache->has($ip_address)) {
101+
return $this->cache->get($ip_address);
102+
}
103+
104+
$url = self::API_URL;
105+
if ($ip_address) {
106+
$url .= "/$ip_address";
107+
}
108+
109+
try {
110+
$response = $this->http_client->request(
111+
self::REQUEST_TYPE_GET,
112+
$url
113+
);
114+
} catch (GuzzleException $e) {
115+
throw new IPinfoException($e->getMessage());
116+
} catch (Exception $e) {
117+
throw new IPinfoException($e->getMessage());
118+
}
119+
120+
if ($response->getStatusCode() == self::STATUS_CODE_QUOTA_EXCEEDED) {
121+
throw new IPinfoException('IPinfo request quota exceeded.');
122+
} elseif ($response->getStatusCode() >= 400) {
123+
throw new IPinfoException('Exception: ' . json_encode([
109124
'status' => $response->getStatusCode(),
110125
'reason' => $response->getReasonPhrase(),
111-
]));
112-
}
113-
114-
$raw_details = json_decode($response->getBody(), true);
115-
$this->cache->set($ip_address, $raw_details);
126+
]));
116127
}
117128

118-
return $this->cache->get($ip_address);
129+
$raw_details = json_decode($response->getBody(), true);
130+
$this->cache->set($ip_address, $raw_details);
131+
132+
return $raw_details;
119133
}
120134

121135
/**
122136
* Build headers for API request.
123137
* @return array Headers for API request.
124138
*/
125-
public function buildHeaders()
139+
private function buildHeaders()
126140
{
127141
$headers = [
128-
'user-agent' => 'IPinfoClient/PHP/1.0',
129-
'accept' => 'application/json',
142+
'user-agent' => 'IPinfoClient/PHP/2.0',
143+
'accept' => 'application/json',
130144
];
131145

132146
if ($this->access_token) {
133147
$headers['authorization'] = "Bearer {$this->access_token}";
134148
}
135149

136-
return ['headers' => $headers];
150+
return $headers;
137151
}
138152

139153
/**

0 commit comments

Comments
 (0)