Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8febab1fe4 | ||
|
|
f0430b613d | ||
|
|
e3289ec416 | ||
|
|
1d1dcec74c | ||
|
|
630765f924 | ||
|
|
b55d42b5cd | ||
|
|
044ca4d085 | ||
|
|
3ba84992c8 | ||
|
|
a6c1f9378e | ||
|
|
1c0817d133 | ||
|
|
59a51ef34d | ||
|
|
3e0fc2a837 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "maxmind-db"]
|
||||||
|
path = maxmind-db
|
||||||
|
url = git://github.com/maxmind/MaxMind-DB.git
|
||||||
@@ -1,6 +1,14 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.4.0 (2013-07-16)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* This is the first release with the GeoIP2 database reader. Please see the
|
||||||
|
`README.md` file and the `\GeoIp2\Database\Reader` class.
|
||||||
|
* The general exception classes were replaced with specific exception classes
|
||||||
|
representing particular types of errors, such as an authentication error.
|
||||||
|
|
||||||
0.3.0 (2013-07-12)
|
0.3.0 (2013-07-12)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|||||||
91
README.md
91
README.md
@@ -13,27 +13,22 @@ To provide feedback or get support during the beta, please see the
|
|||||||
|
|
||||||
## Description ##
|
## Description ##
|
||||||
|
|
||||||
Currently, this distribution provides an API for the [GeoIP2 web services]
|
This distribution provides an API for the [GeoIP2 web services]
|
||||||
(http://dev.maxmind.com/geoip/geoip2/web-services).
|
(http://dev.maxmind.com/geoip/geoip2/web-services) and the [GeoLite2
|
||||||
|
databases](http://dev.maxmind.com/geoip/geoip2/geolite2/). The commercial
|
||||||
In the future, this distribution will also provide the same API for the
|
GeoIP2 databases have not yet been released as a downloadable product.
|
||||||
GeoIP2 downloadable databases. These databases have not yet been
|
|
||||||
released as a downloadable product.
|
|
||||||
|
|
||||||
See ``GeoIp2\WebService\Client`` for details on the web service client
|
|
||||||
API.
|
|
||||||
|
|
||||||
## Installation ##
|
## Installation ##
|
||||||
|
|
||||||
### Define Your Dependencies ###
|
### Define Your Dependencies ###
|
||||||
|
|
||||||
We recommend installing this package with [Composer](http://getcomposer.org/).
|
We recommend installing this package with [Composer](http://getcomposer.org/).
|
||||||
To do this, add ```geoip2/geoip2``` to your ```composer.json``` file.
|
To do this, add `geoip2/geoip2` to your `composer.json` file.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"geoip2/geoip2": "0.3.*"
|
"geoip2/geoip2": "0.4.*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -60,11 +55,43 @@ You can autoload all dependencies by adding this to your code:
|
|||||||
```
|
```
|
||||||
require 'vendor/autoload.php';
|
require 'vendor/autoload.php';
|
||||||
```
|
```
|
||||||
|
## Database Reader ##
|
||||||
|
|
||||||
## Usage ##
|
### Usage ###
|
||||||
|
|
||||||
To use this API, you must create a new ``\GeoIp2\WebService\Client``
|
To use this API, you must create a new `\GeoIp2\Database\Reader` object with
|
||||||
object with your ``$userId`` and ``$licenseKey``, then you call the method
|
the path to the database file as the first argument to the constructor. You
|
||||||
|
may then call the method corresponding to the database you are using.
|
||||||
|
|
||||||
|
If the lookup succeeds, the method call will return a model class for the
|
||||||
|
record in the database. This model in turn contains multiple container
|
||||||
|
classes for the different parts of the data such as the city in which the
|
||||||
|
IP address is located.
|
||||||
|
|
||||||
|
If the record is not found, a `\GeoIp2\Exception\AddressNotFoundException`
|
||||||
|
is returned. If the database is invalid or corrupt, a
|
||||||
|
`\MaxMind\Db\InvalidDatabaseException` will be thrown.
|
||||||
|
|
||||||
|
See the API documentation for more details.
|
||||||
|
|
||||||
|
### Example ###
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
require_once 'vendor/autoload.php';
|
||||||
|
use \GeoIp2\Database\Reader;
|
||||||
|
|
||||||
|
$reader = new Reader('/usr/local/share/GeoIP2/GeoIP2-City.mmdb');
|
||||||
|
$record = $reader->city('24.24.24.24');
|
||||||
|
print($record->country->isoCode);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Web Service Client ##
|
||||||
|
|
||||||
|
### Usage ###
|
||||||
|
|
||||||
|
To use this API, you must create a new `\GeoIp2\WebService\Client`
|
||||||
|
object with your `$userId` and `$licenseKey`, then you call the method
|
||||||
corresponding to a specific end point, passing it the IP address you want to
|
corresponding to a specific end point, passing it the IP address you want to
|
||||||
look up.
|
look up.
|
||||||
|
|
||||||
@@ -72,9 +99,11 @@ If the request succeeds, the method call will return a model class for the end
|
|||||||
point you called. This model in turn contains multiple record classes, each of
|
point you called. This model in turn contains multiple record classes, each of
|
||||||
which represents part of the data returned by the web service.
|
which represents part of the data returned by the web service.
|
||||||
|
|
||||||
|
If there is an error, a structured exception is thrown.
|
||||||
|
|
||||||
See the API documentation for more details.
|
See the API documentation for more details.
|
||||||
|
|
||||||
## Example ##
|
### Example ###
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
@@ -83,30 +112,10 @@ use \GeoIp2\WebService\Client;
|
|||||||
|
|
||||||
$client = new Client(42, 'abcdef123456');
|
$client = new Client(42, 'abcdef123456');
|
||||||
$omni = $client->omni('24.24.24.24');
|
$omni = $client->omni('24.24.24.24');
|
||||||
echo $omni->country->isoCode;
|
print($omni->country->isoCode);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Exceptions ##
|
### What data is returned? ###
|
||||||
|
|
||||||
For details on the possible errors returned by the web service itself, see
|
|
||||||
the
|
|
||||||
[GeoIP2 web service docs](http://dev.maxmind.com/geoip2/geoip/web-service).
|
|
||||||
|
|
||||||
If the web service returns an explicit error document, this is thrown as a
|
|
||||||
```\GeoIp2\Exception\WebServiceException```. If some other sort of transport
|
|
||||||
error occurs, this is thrown as a ```\GeoIp2\Exception\HttpException```.
|
|
||||||
The difference is that the web service error includes an error message and
|
|
||||||
error code delivered by the web service. The latter is thrown when some sort
|
|
||||||
of unanticipated error occurs, such as the web service returning a 500 or an
|
|
||||||
invalid error document.
|
|
||||||
|
|
||||||
If the web service returns any status code besides 200, 4xx, or 5xx, this also
|
|
||||||
becomes a ```\GeoIp2\Exception\HttpException```.
|
|
||||||
|
|
||||||
Finally, if the web service returns a 200 but the body is invalid, the client
|
|
||||||
throws a ```\GeoIp2\Exception\GeoIp2Exception```.
|
|
||||||
|
|
||||||
## What data is returned? ##
|
|
||||||
|
|
||||||
While many of the end points return the same basic records, the attributes
|
While many of the end points return the same basic records, the attributes
|
||||||
which can be populated vary between end points. In addition, while an end
|
which can be populated vary between end points. In addition, while an end
|
||||||
@@ -120,8 +129,8 @@ See the
|
|||||||
[GeoIP2 web service docs](http://dev.maxmind.com/geoip/geoip2/web-services)
|
[GeoIP2 web service docs](http://dev.maxmind.com/geoip/geoip2/web-services)
|
||||||
for details on what data each end point may return.
|
for details on what data each end point may return.
|
||||||
|
|
||||||
The only piece of data which is always returned is the ```ipAddress```
|
The only piece of data which is always returned is the `ipAddress`
|
||||||
attribute in the ``GeoIp2\Record\Traits`` record.
|
attribute in the `GeoIp2\Record\Traits` record.
|
||||||
|
|
||||||
Every record class attribute has a corresponding predicate method so you can
|
Every record class attribute has a corresponding predicate method so you can
|
||||||
check to see if the attribute is set.
|
check to see if the attribute is set.
|
||||||
@@ -131,10 +140,10 @@ check to see if the attribute is set.
|
|||||||
[GeoNames](http://www.geonames.org/) offers web services and downloadable
|
[GeoNames](http://www.geonames.org/) offers web services and downloadable
|
||||||
databases with data on geographical features around the world, including
|
databases with data on geographical features around the world, including
|
||||||
populated places. They offer both free and paid premium data. Each
|
populated places. They offer both free and paid premium data. Each
|
||||||
feature is unique identified by a ```geonameId```, which is an integer.
|
feature is unique identified by a `geonameId`, which is an integer.
|
||||||
|
|
||||||
Many of the records returned by the GeoIP2 web services and databases
|
Many of the records returned by the GeoIP2 web services and databases
|
||||||
include a ```geonameId``` property. This is the ID of a geographical feature
|
include a `geonameId` property. This is the ID of a geographical feature
|
||||||
(city, region, country, etc.) in the GeoNames database.
|
(city, region, country, etc.) in the GeoNames database.
|
||||||
|
|
||||||
Some of the data that MaxMind provides is also sourced from GeoNames. We
|
Some of the data that MaxMind provides is also sourced from GeoNames. We
|
||||||
|
|||||||
@@ -58,6 +58,6 @@ git push git@github.com:maxmind/GeoIP2-php.git
|
|||||||
git push
|
git push
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
git tag $TAG
|
git tag -a $TAG
|
||||||
git push
|
git push
|
||||||
git push --tags
|
git push --tags
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"guzzle/guzzle": "3.*",
|
"guzzle/guzzle": "3.*",
|
||||||
|
"maxmind-db/reader": "0.1.*",
|
||||||
"php": ">=5.3.1"
|
"php": ">=5.3.1"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
|||||||
1
maxmind-db
Submodule
1
maxmind-db
Submodule
Submodule maxmind-db added at f7b9342b84
150
src/GeoIp2/Database/Reader.php
Normal file
150
src/GeoIp2/Database/Reader.php
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GeoIp2\Database;
|
||||||
|
|
||||||
|
use GeoIp2\Exception\AddressNotFoundException;
|
||||||
|
use GeoIp2\Model\City;
|
||||||
|
use GeoIp2\Model\CityIspOrg;
|
||||||
|
use GeoIp2\Model\Country;
|
||||||
|
use GeoIp2\Model\Omni;
|
||||||
|
use MaxMind\Db\Reader as DbReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instances of this class provide a reader for the GeoIP2 database format.
|
||||||
|
* IP addresses can be looked up using the <code>country</code>
|
||||||
|
* and <code>city</code> methods. We also provide <code>cityIspOrg</code>
|
||||||
|
* and <code>omni</code> methods to ease compatibility with the web service
|
||||||
|
* client, although we may offer the ability to specify additional databases
|
||||||
|
* to replicate these web services in the future (e.g., the ISP/Org database).
|
||||||
|
*
|
||||||
|
* **Usage**
|
||||||
|
*
|
||||||
|
* The basic API for this class is the same for every database. First, you
|
||||||
|
* create a reader object, specifying a file name. You then call the method
|
||||||
|
* corresponding to the specific database, passing it the IP address you want
|
||||||
|
* to look up.
|
||||||
|
*
|
||||||
|
* If the request succeeds, the method call will return a model class for
|
||||||
|
* the method you called. This model in turn contains multiple record classes,
|
||||||
|
* each of which represents part of the data returned by the database. If
|
||||||
|
* the database does not contain the requested information, the attributes
|
||||||
|
* on the record class will have a <code>null</code> value.
|
||||||
|
*
|
||||||
|
* If the address is not in the database, an
|
||||||
|
* {@link \GeoIp2\Exception\AddressNotFoundException} exception will be
|
||||||
|
* thrown. If an invalid IP address is passed to one of the methods, a
|
||||||
|
* SPL {@link \InvalidArgumentException} will be thrown. If the database is
|
||||||
|
* corrupt or invalid, a {@link \MaxMind\Db\Reader\InvalidDatabaseException}
|
||||||
|
* will be thrown.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Reader
|
||||||
|
{
|
||||||
|
private $dbReader;
|
||||||
|
private $languages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $filename The path to the GeoIP2 database file.
|
||||||
|
* @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database
|
||||||
|
* is corrupt or invalid
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$filename,
|
||||||
|
$languages = array('en')
|
||||||
|
) {
|
||||||
|
$this->dbReader = new DbReader($filename);
|
||||||
|
$this->languages = $languages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a GeoIP2 City model.
|
||||||
|
*
|
||||||
|
* @param string $ipAddress IPv4 or IPv6 address as a string.
|
||||||
|
*
|
||||||
|
* @return \GeoIp2\Model\City
|
||||||
|
*
|
||||||
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address is
|
||||||
|
* not in the database.
|
||||||
|
* @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database
|
||||||
|
* is corrupt or invalid
|
||||||
|
*/
|
||||||
|
public function city($ipAddress)
|
||||||
|
{
|
||||||
|
return $this->modelFor('City', $ipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a GeoIP2 Country model.
|
||||||
|
*
|
||||||
|
* @param string $ipAddress IPv4 or IPv6 address as a string.
|
||||||
|
*
|
||||||
|
* @return \GeoIp2\Model\Country
|
||||||
|
*
|
||||||
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address is
|
||||||
|
* not in the database.
|
||||||
|
* @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database
|
||||||
|
* is corrupt or invalid
|
||||||
|
*/
|
||||||
|
public function country($ipAddress)
|
||||||
|
{
|
||||||
|
return $this->modelFor('Country', $ipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a GeoIP2 City/ISP/Org model.
|
||||||
|
*
|
||||||
|
* @param string $ipAddress IPv4 or IPv6 address as a string.
|
||||||
|
*
|
||||||
|
* @return \GeoIp2\Model\CityIspOrg
|
||||||
|
*
|
||||||
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address is
|
||||||
|
* not in the database.
|
||||||
|
* @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database
|
||||||
|
* is corrupt or invalid
|
||||||
|
*/
|
||||||
|
public function cityIspOrg($ipAddress)
|
||||||
|
{
|
||||||
|
return $this->modelFor('CityIspOrg', $ipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns a GeoIP2 Omni model.
|
||||||
|
*
|
||||||
|
* @param string $ipAddress IPv4 or IPv6 address as a string.
|
||||||
|
*
|
||||||
|
* @return \GeoIp2\Model\Omni
|
||||||
|
*
|
||||||
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address is
|
||||||
|
* not in the database.
|
||||||
|
* @throws \MaxMind\Db\Reader\InvalidDatabaseException if the database
|
||||||
|
* is corrupt or invalid
|
||||||
|
*/
|
||||||
|
public function omni($ipAddress)
|
||||||
|
{
|
||||||
|
return $this->modelFor('Omni', $ipAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function modelFor($class, $ipAddress)
|
||||||
|
{
|
||||||
|
$record = $this->dbReader->get($ipAddress);
|
||||||
|
if ($record === null) {
|
||||||
|
throw new AddressNotFoundException(
|
||||||
|
"The address $ipAddress is not in the database."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$record['traits']['ip_address'] = $ipAddress;
|
||||||
|
$class = "GeoIp2\\Model\\" . $class;
|
||||||
|
|
||||||
|
return new $class($record, $this->languages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the GeoIP2 database and returns the resources to the system.
|
||||||
|
*/
|
||||||
|
public function close()
|
||||||
|
{
|
||||||
|
$this->dbReader->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/GeoIp2/Exception/AddressNotFoundException.php
Normal file
10
src/GeoIp2/Exception/AddressNotFoundException.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GeoIp2\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a generic error.
|
||||||
|
*/
|
||||||
|
class AddressNotFoundException extends GeoIp2Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
10
src/GeoIp2/Exception/AuthenticationException.php
Normal file
10
src/GeoIp2/Exception/AuthenticationException.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GeoIp2\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a generic error.
|
||||||
|
*/
|
||||||
|
class AuthenticationException extends GeoIp2Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ namespace GeoIp2\Exception;
|
|||||||
* This class represents an error returned by MaxMind's GeoIP2
|
* This class represents an error returned by MaxMind's GeoIP2
|
||||||
* web service.
|
* web service.
|
||||||
*/
|
*/
|
||||||
class WebServiceException extends HttpException
|
class InvalidRequestException extends HttpException
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The code returned by the MaxMind web service
|
* The code returned by the MaxMind web service
|
||||||
10
src/GeoIp2/Exception/OutOfQueriesException.php
Normal file
10
src/GeoIp2/Exception/OutOfQueriesException.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GeoIp2\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a generic error.
|
||||||
|
*/
|
||||||
|
class OutOfQueriesException extends GeoIp2Exception
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -4,7 +4,10 @@ namespace GeoIp2\WebService;
|
|||||||
|
|
||||||
use GeoIp2\Exception\GeoIp2Exception;
|
use GeoIp2\Exception\GeoIp2Exception;
|
||||||
use GeoIp2\Exception\HttpException;
|
use GeoIp2\Exception\HttpException;
|
||||||
use GeoIp2\Exception\WebServiceException;
|
use GeoIp2\Exception\AddressNotFoundException;
|
||||||
|
use GeoIp2\Exception\AuthenticationException;
|
||||||
|
use GeoIp2\Exception\InvalidRequestException;
|
||||||
|
use GeoIp2\Exception\OutOfQueriesException;
|
||||||
use GeoIp2\Model\City;
|
use GeoIp2\Model\City;
|
||||||
use GeoIp2\Model\CityIspOrg;
|
use GeoIp2\Model\CityIspOrg;
|
||||||
use GeoIp2\Model\Country;
|
use GeoIp2\Model\Country;
|
||||||
@@ -44,26 +47,6 @@ use Guzzle\Http\Exception\ServerErrorResponseException;
|
|||||||
* service.
|
* service.
|
||||||
*
|
*
|
||||||
* If the request fails, the client class throws an exception.
|
* If the request fails, the client class throws an exception.
|
||||||
*
|
|
||||||
* **Exceptions**
|
|
||||||
*
|
|
||||||
* For details on the possible errors returned by the web service itself, see
|
|
||||||
* {@link http://dev.maxmind.com/geoip2/geoip/web-services the GeoIP2 web
|
|
||||||
* service docs}.
|
|
||||||
*
|
|
||||||
* If the web service returns an explicit error document, this is thrown as a
|
|
||||||
* {@link \GeoIp2\Exception\WebServiceException}. If some other sort of
|
|
||||||
* transport error occurs, this is thrown as a {@link
|
|
||||||
* \GeoIp2\Exception\HttpException}. The difference is that the web service
|
|
||||||
* error includes an error message and error code delivered by the web
|
|
||||||
* service. The latter is thrown when some sort of unanticipated error occurs,
|
|
||||||
* such as the web service returning a 500 or an invalid error document.
|
|
||||||
*
|
|
||||||
* If the web service returns any status code besides 200, 4xx, or 5xx, this
|
|
||||||
* also becomes a {@link \GeoIp2\Exception\HttpException}.
|
|
||||||
*
|
|
||||||
* Finally, if the web service returns a 200 but the body is invalid, the
|
|
||||||
* client throws a {@link \GeoIp2\Exception\GeoIp2Exception}.
|
|
||||||
*/
|
*/
|
||||||
class Client
|
class Client
|
||||||
{
|
{
|
||||||
@@ -108,12 +91,23 @@ class Client
|
|||||||
*
|
*
|
||||||
* @return \GeoIp2\Model\City
|
* @return \GeoIp2\Model\City
|
||||||
*
|
*
|
||||||
* @throws \GeoIp2\Exception\GeoIp2Exception if there was a generic
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address you
|
||||||
* error processing your request.
|
* provided is not in our database (e.g., a private address).
|
||||||
* @throws \GeoIp2\Exception\HttpException if there was an HTTP transport
|
* @throws \GeoIp2\Exception\AuthenticationException if there is a problem
|
||||||
* error.
|
* with the user ID or license key that you provided.
|
||||||
* @throws \GeoIp2\Exception\WebServiceException if an error was returned
|
* @throws \GeoIp2\Exception\QutOfQueriesException if your account is out
|
||||||
* by MaxMind's GeoIP2 web service.
|
* of queries.
|
||||||
|
* @throws \GeoIp2\Exception\InvalidRequestException} if your request was
|
||||||
|
* received by the web service but is invalid for some other reason.
|
||||||
|
* This may indicate an issue with this API. Please report the error to
|
||||||
|
* MaxMind.
|
||||||
|
* @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error
|
||||||
|
* code or message was returned. This could indicate a problem with the
|
||||||
|
* connection between your server and the web service or that the web
|
||||||
|
* service returned an invalid document or 500 error code.
|
||||||
|
* @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
|
||||||
|
* class to the above exceptions. It will be thrown directly if a 200
|
||||||
|
* status code is returned but the body is invalid.
|
||||||
*/
|
*/
|
||||||
public function city($ipAddress = 'me')
|
public function city($ipAddress = 'me')
|
||||||
{
|
{
|
||||||
@@ -129,12 +123,23 @@ class Client
|
|||||||
*
|
*
|
||||||
* @return \GeoIp2\Model\Country
|
* @return \GeoIp2\Model\Country
|
||||||
*
|
*
|
||||||
* @throws \GeoIp2\Exception\GeoIp2Exception if there was a generic
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address you
|
||||||
* error processing your request.
|
* provided is not in our database (e.g., a private address).
|
||||||
* @throws \GeoIp2\Exception\HttpException if there was an HTTP transport
|
* @throws \GeoIp2\Exception\AuthenticationException if there is a problem
|
||||||
* error.
|
* with the user ID or license key that you provided.
|
||||||
* @throws \GeoIp2\Exception\WebServiceException if an error was returned
|
* @throws \GeoIp2\Exception\QutOfQueriesException if your account is out
|
||||||
* by MaxMind's GeoIP2 web service.
|
* of queries.
|
||||||
|
* @throws \GeoIp2\Exception\InvalidRequestException} if your request was
|
||||||
|
* received by the web service but is invalid for some other reason.
|
||||||
|
* This may indicate an issue with this API. Please report the error to
|
||||||
|
* MaxMind.
|
||||||
|
* @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error
|
||||||
|
* code or message was returned. This could indicate a problem with the
|
||||||
|
* connection between your server and the web service or that the web
|
||||||
|
* service returned an invalid document or 500 error code.
|
||||||
|
* @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
|
||||||
|
* class to the above exceptions. It will be thrown directly if a 200
|
||||||
|
* status code is returned but the body is invalid.
|
||||||
*/
|
*/
|
||||||
public function country($ipAddress = 'me')
|
public function country($ipAddress = 'me')
|
||||||
{
|
{
|
||||||
@@ -150,12 +155,23 @@ class Client
|
|||||||
*
|
*
|
||||||
* @return \GeoIp2\Model\CityIspOrg
|
* @return \GeoIp2\Model\CityIspOrg
|
||||||
*
|
*
|
||||||
* @throws \GeoIp2\Exception\GeoIp2Exception if there was a generic
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address you
|
||||||
* error processing your request.
|
* provided is not in our database (e.g., a private address).
|
||||||
* @throws \GeoIp2\Exception\HttpException if there was an HTTP transport
|
* @throws \GeoIp2\Exception\AuthenticationException if there is a problem
|
||||||
* error.
|
* with the user ID or license key that you provided.
|
||||||
* @throws \GeoIp2\Exception\WebServiceException if an error was returned
|
* @throws \GeoIp2\Exception\QutOfQueriesException if your account is out
|
||||||
* by MaxMind's GeoIP2 web service.
|
* of queries.
|
||||||
|
* @throws \GeoIp2\Exception\InvalidRequestException} if your request was
|
||||||
|
* received by the web service but is invalid for some other reason.
|
||||||
|
* This may indicate an issue with this API. Please report the error to
|
||||||
|
* MaxMind.
|
||||||
|
* @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error
|
||||||
|
* code or message was returned. This could indicate a problem with the
|
||||||
|
* connection between your server and the web service or that the web
|
||||||
|
* service returned an invalid document or 500 error code.
|
||||||
|
* @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
|
||||||
|
* class to the above exceptions. It will be thrown directly if a 200
|
||||||
|
* status code is returned but the body is invalid.
|
||||||
*/
|
*/
|
||||||
public function cityIspOrg($ipAddress = 'me')
|
public function cityIspOrg($ipAddress = 'me')
|
||||||
{
|
{
|
||||||
@@ -171,12 +187,23 @@ class Client
|
|||||||
*
|
*
|
||||||
* @return \GeoIp2\Model\Omni
|
* @return \GeoIp2\Model\Omni
|
||||||
*
|
*
|
||||||
* @throws \GeoIp2\Exception\GeoIp2Exception if there was a generic
|
* @throws \GeoIp2\Exception\AddressNotFoundException if the address you
|
||||||
* error processing your request.
|
* provided is not in our database (e.g., a private address).
|
||||||
* @throws \GeoIp2\Exception\HttpException if there was an HTTP transport
|
* @throws \GeoIp2\Exception\AuthenticationException if there is a problem
|
||||||
* error.
|
* with the user ID or license key that you provided.
|
||||||
* @throws \GeoIp2\Exception\WebServiceException if an error was returned
|
* @throws \GeoIp2\Exception\QutOfQueriesException if your account is out
|
||||||
* by MaxMind's GeoIP2 web service.
|
* of queries.
|
||||||
|
* @throws \GeoIp2\Exception\InvalidRequestException} if your request was
|
||||||
|
* received by the web service but is invalid for some other reason.
|
||||||
|
* This may indicate an issue with this API. Please report the error to
|
||||||
|
* MaxMind.
|
||||||
|
* @throws \GeoIp2\Exception\HttpException if an unexpected HTTP error
|
||||||
|
* code or message was returned. This could indicate a problem with the
|
||||||
|
* connection between your server and the web service or that the web
|
||||||
|
* service returned an invalid document or 500 error code.
|
||||||
|
* @throws \GeoIp2\Exception\GeoIp2Exception This serves as the parent
|
||||||
|
* class to the above exceptions. It will be thrown directly if a 200
|
||||||
|
* status code is returned but the body is invalid.
|
||||||
*/
|
*/
|
||||||
public function omni($ipAddress = 'me')
|
public function omni($ipAddress = 'me')
|
||||||
{
|
{
|
||||||
@@ -191,11 +218,8 @@ class Client
|
|||||||
$this->guzzleClient : new GuzzleClient();
|
$this->guzzleClient : new GuzzleClient();
|
||||||
$request = $client->get($uri, array('Accept' => 'application/json'));
|
$request = $client->get($uri, array('Accept' => 'application/json'));
|
||||||
$request->setAuth($this->userId, $this->licenseKey);
|
$request->setAuth($this->userId, $this->licenseKey);
|
||||||
$ua = $request->getHeader('User-Agent');
|
$this->setUserAgent($request);
|
||||||
$ua = "GeoIP2 PHP API ($ua)";
|
|
||||||
$request->setHeader('User-Agent', $ua);
|
|
||||||
|
|
||||||
$response = null;
|
|
||||||
try {
|
try {
|
||||||
$response = $request->send();
|
$response = $request->send();
|
||||||
} catch (ClientErrorResponseException $e) {
|
} catch (ClientErrorResponseException $e) {
|
||||||
@@ -273,8 +297,7 @@ class Client
|
|||||||
$uri
|
$uri
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$this->handleWebServiceError(
|
||||||
throw new WebServiceException(
|
|
||||||
$body['error'],
|
$body['error'],
|
||||||
$body['code'],
|
$body['code'],
|
||||||
$status,
|
$status,
|
||||||
@@ -282,6 +305,28 @@ class Client
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleWebServiceError($message, $code, $status, $uri)
|
||||||
|
{
|
||||||
|
switch ($code) {
|
||||||
|
case 'IP_ADDRESS_NOT_FOUND':
|
||||||
|
case 'IP_ADDRESS_RESERVED':
|
||||||
|
throw new AddressNotFoundException($message);
|
||||||
|
case 'AUTHORIZATION_INVALID':
|
||||||
|
case 'LICENSE_KEY_REQUIRED':
|
||||||
|
case 'USER_ID_REQUIRED':
|
||||||
|
throw new AuthenticationException($message);
|
||||||
|
case 'OUT_OF_QUERIES':
|
||||||
|
throw new OutOfQueriesException($message);
|
||||||
|
default:
|
||||||
|
throw new InvalidRequestException(
|
||||||
|
$message,
|
||||||
|
$code,
|
||||||
|
$status,
|
||||||
|
$uri
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function handle5xx($response, $uri)
|
private function handle5xx($response, $uri)
|
||||||
{
|
{
|
||||||
$status = $response->getStatusCode();
|
$status = $response->getStatusCode();
|
||||||
@@ -305,6 +350,13 @@ class Client
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setUserAgent($request)
|
||||||
|
{
|
||||||
|
$userAgent = $request->getHeader('User-Agent');
|
||||||
|
$userAgent = "GeoIP2 PHP API ($userAgent)";
|
||||||
|
$request->setHeader('User-Agent', $userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
private function baseUri()
|
private function baseUri()
|
||||||
{
|
{
|
||||||
return 'https://' . $this->host . '/geoip/v2.0';
|
return 'https://' . $this->host . '/geoip/v2.0';
|
||||||
|
|||||||
80
tests/GeoIp2/Test/Database/ReaderTest.php
Normal file
80
tests/GeoIp2/Test/Database/ReaderTest.php
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace GeoIp2\Test\WebService;
|
||||||
|
|
||||||
|
use GeoIp2\Database\Reader;
|
||||||
|
|
||||||
|
class ReaderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testDefaultLanguage()
|
||||||
|
{
|
||||||
|
$reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb');
|
||||||
|
// Needed for PHP 5.3
|
||||||
|
$that = $this;
|
||||||
|
$this->checkAllMethods(
|
||||||
|
function ($method) use (&$that, &$reader) {
|
||||||
|
$record = $reader->$method('81.2.69.160');
|
||||||
|
$that->assertEquals('United Kingdom', $record->country->name);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$reader->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLanguageList()
|
||||||
|
{
|
||||||
|
$reader = new Reader(
|
||||||
|
'maxmind-db/test-data/GeoIP2-City-Test.mmdb',
|
||||||
|
array('xx', 'ru', 'pt-BR', 'es', 'en')
|
||||||
|
);
|
||||||
|
$that = $this;
|
||||||
|
$this->checkAllMethods(
|
||||||
|
function ($method) use (&$that, &$reader) {
|
||||||
|
$record = $reader->$method('81.2.69.160');
|
||||||
|
$that->assertEquals('Великобритания', $record->country->name);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$reader->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHasIpAddress()
|
||||||
|
{
|
||||||
|
$reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb');
|
||||||
|
$that = $this;
|
||||||
|
$this->checkAllMethods(
|
||||||
|
function ($method) use (&$that, &$reader) {
|
||||||
|
$record = $reader->$method('81.2.69.160');
|
||||||
|
$that->assertEquals('81.2.69.160', $record->traits->ipAddress);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$reader->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AddressNotFoundException
|
||||||
|
* @expectedExceptionMessage The address 10.10.10.10 is not in the database.
|
||||||
|
*/
|
||||||
|
public function testUnknownAddress()
|
||||||
|
{
|
||||||
|
$reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb');
|
||||||
|
$reader->city('10.10.10.10');
|
||||||
|
$reader->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage invalid is not a valid IP address
|
||||||
|
*/
|
||||||
|
public function testInvalidAddress()
|
||||||
|
{
|
||||||
|
$reader = new Reader('maxmind-db/test-data/GeoIP2-City-Test.mmdb');
|
||||||
|
$reader->city('invalid');
|
||||||
|
$reader->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkAllMethods($testCb)
|
||||||
|
{
|
||||||
|
foreach (array('city', 'cityIspOrg', 'country', 'omni') as $method) {
|
||||||
|
$testCb($method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,6 +82,54 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
null,
|
null,
|
||||||
'text/plain'
|
'text/plain'
|
||||||
),
|
),
|
||||||
|
'1.2.3.13'=> $this->response(
|
||||||
|
'error',
|
||||||
|
404,
|
||||||
|
array(
|
||||||
|
'code' => 'IP_ADDRESS_NOT_FOUND',
|
||||||
|
'error' => 'The address "1.2.3.13" is not in our database.'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'1.2.3.14'=> $this->response(
|
||||||
|
'error',
|
||||||
|
400,
|
||||||
|
array(
|
||||||
|
'code' => 'IP_ADDRESS_RESERVED',
|
||||||
|
'error' => 'The address "1.2.3.14" is a private address.'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'1.2.3.15'=> $this->response(
|
||||||
|
'error',
|
||||||
|
401,
|
||||||
|
array(
|
||||||
|
'code' => 'AUTHORIZATION_INVALID',
|
||||||
|
'error' => 'A user ID and license key are required to use this service'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'1.2.3.16'=> $this->response(
|
||||||
|
'error',
|
||||||
|
401,
|
||||||
|
array(
|
||||||
|
'code' => 'LICENSE_KEY_REQUIRED',
|
||||||
|
'error' => 'A license key is required to use this service'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'1.2.3.17'=> $this->response(
|
||||||
|
'error',
|
||||||
|
401,
|
||||||
|
array(
|
||||||
|
'code' => 'USER_ID_REQUIRED',
|
||||||
|
'error' => 'A user ID is required to use this service'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'1.2.3.18'=> $this->response(
|
||||||
|
'error',
|
||||||
|
402,
|
||||||
|
array(
|
||||||
|
'code' => 'OUT_OF_QUERIES',
|
||||||
|
'error' => 'The license key you have provided is out of queries.'
|
||||||
|
)
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return $responses[$ip];
|
return $responses[$ip];
|
||||||
}
|
}
|
||||||
@@ -207,7 +255,7 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException GeoIp2\Exception\WebServiceException
|
* @expectedException GeoIp2\Exception\InvalidRequestException
|
||||||
* @expectedExceptionCode 400
|
* @expectedExceptionCode 400
|
||||||
* @expectedExceptionMessage The value "1.2.3" is not a valid ip address
|
* @expectedExceptionMessage The value "1.2.3" is not a valid ip address
|
||||||
*/
|
*/
|
||||||
@@ -216,7 +264,6 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
$client = $this->client($this->getResponse('1.2.3.6'));
|
$client = $this->client($this->getResponse('1.2.3.6'));
|
||||||
|
|
||||||
$client->country('1.2.3.6');
|
$client->country('1.2.3.6');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -293,6 +340,72 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
|||||||
$client->country('1.2.3.12');
|
$client->country('1.2.3.12');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AddressNotFoundException
|
||||||
|
* @expectedExceptionMessage The address "1.2.3.13" is not in our database.
|
||||||
|
*/
|
||||||
|
public function testAddressNotFoundException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.13'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.13');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AddressNotFoundException
|
||||||
|
* @expectedExceptionMessage The address "1.2.3.14" is a private address.
|
||||||
|
*/
|
||||||
|
public function testAddressReservedException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.14'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.14');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AuthenticationException
|
||||||
|
* @expectedExceptionMessage A user ID and license key are required to use this service
|
||||||
|
*/
|
||||||
|
public function testAuthorizationException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.15'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.15');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AuthenticationException
|
||||||
|
* @expectedExceptionMessage A license key is required to use this service
|
||||||
|
*/
|
||||||
|
public function testMissingLicenseKeyException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.16'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.16');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\AuthenticationException
|
||||||
|
* @expectedExceptionMessage A user ID is required to use this service
|
||||||
|
*/
|
||||||
|
public function testMissingUserIdException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.17'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.17');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException GeoIp2\Exception\OutOfQueriesException
|
||||||
|
* @expectedExceptionMessage The license key you have provided is out of queries.
|
||||||
|
*/
|
||||||
|
public function testOutOfQueriesException()
|
||||||
|
{
|
||||||
|
$client = $this->client($this->getResponse('1.2.3.18'));
|
||||||
|
|
||||||
|
$client->country('1.2.3.18');
|
||||||
|
}
|
||||||
|
|
||||||
public function testParams()
|
public function testParams()
|
||||||
{
|
{
|
||||||
$plugin = new MockPlugin();
|
$plugin = new MockPlugin();
|
||||||
|
|||||||
Reference in New Issue
Block a user