Package-update-patch

Update Torann/GeoIP package from 0.2 to 1.0.0 which is being used to
show country code in phone nuber in various forms.
This commit is contained in:
Manish Verma
2016-11-03 15:28:03 +05:30
parent 580479f087
commit ca32203d6f
52 changed files with 2446 additions and 814 deletions

74
vendor/torann/geoip/src/Cache.php vendored Normal file
View File

@@ -0,0 +1,74 @@
<?php
namespace Torann\GeoIP;
use Illuminate\Cache\CacheManager;
class Cache
{
/**
* Instance of cache manager.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* Lifetime of the cache.
*
* @var int
*/
protected $expires;
/**
* Create a new cache instance.
*
* @param CacheManager $cache
* @param array $tags
* @param int $expires
*/
public function __construct(CacheManager $cache, $tags, $expires = 30)
{
$this->cache = $tags ? $cache->tags($tags) : $cache;
$this->expires = $expires;
}
/**
* Get an item from the cache.
*
* @param string $name
*
* @return Location|null
*/
public function get($name)
{
$value = $this->cache->get($name);
return is_array($value)
? new Location($value)
: null;
}
/**
* Store an item in cache.
*
* @param string $name
* @param Location $location
*
* @return bool
*/
public function set($name, Location $location)
{
return $this->cache->put($name, $location->toArray(), $this->expires);
}
/**
* Flush cache for tags.
*
* @return bool
*/
public function flush()
{
return $this->cache->flush();
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Torann\GeoIP\Console;
use Illuminate\Console\Command;
class Clear extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'geoip:clear';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Clear GeoIP cached locations.';
/**
* Execute the console command.
*/
public function fire()
{
if ($this->isSupported() === false) {
return $this->output->error('Default cache system does not support tags');
}
$this->performFlush();
}
/**
* Is cache flushing supported.
*
* @return bool
*/
protected function isSupported()
{
return empty(app('geoip')->config('cache_tags')) === false
&& in_array(config('cache.default'), ['file', 'database']) === false;
}
/**
* Flush the cache.
*
* @return void
*/
protected function performFlush()
{
$this->output->write("Clearing cache...");
app('geoip')->getCache()->flush();
$this->output->writeln("<info>complete</info>");
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace Torann\GeoIP\Console;
use Illuminate\Console\Command;
class Update extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'geoip:update';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update GeoIP database files to the latest version';
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
// Get default service
$service = app('geoip')->getService();
// Ensure the selected service supports updating
if (method_exists($service, 'update') === false) {
$this->info('The current service "' . get_class($service). '" does not support updating.');
return;
}
$this->comment('Updating...');
// Perform update
if ($result = $service->update()) {
$this->info($result);
}
else {
$this->error('Update failed!');
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Torann\GeoIP\Contracts;
interface ServiceInterface
{
/**
* The "booting" method of the service.
*
* @return void
*/
public function boot();
/**
* Determine a location based off of
* the provided IP address.
*
* @param string $ip
*
* @return \Torann\GeoIP\Location
*/
public function locate($ip);
/**
* Create a location instance from the provided attributes.
*
* @param array $attributes
*
* @return \Torann\GeoIP\Location
*/
public function hydrate(array $attributes = []);
/**
* Get configuration value.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function config($key, $default = null);
}

View File

@@ -0,0 +1,18 @@
<?php
namespace Torann\GeoIP\Facades;
use Illuminate\Support\Facades\Facade;
class GeoIP extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
return 'geoip';
}
}

309
vendor/torann/geoip/src/GeoIP.php vendored Normal file
View File

@@ -0,0 +1,309 @@
<?php
namespace Torann\GeoIP;
use Exception;
use Monolog\Logger;
use Illuminate\Support\Arr;
use Illuminate\Cache\CacheManager;
use Monolog\Handler\StreamHandler;
class GeoIP
{
/**
* Illuminate config repository instance.
*
* @var array
*/
protected $config;
/**
* Remote Machine IP address.
*
* @var float
*/
protected $remote_ip = null;
/**
* Current location instance.
*
* @var Location
*/
protected $location = null;
/**
* Currency data.
*
* @var array
*/
protected $currencies = null;
/**
* GeoIP service instance.
*
* @var Contracts\ServiceInterface
*/
protected $service;
/**
* Cache manager instance.
*
* @var \Illuminate\Cache\CacheManager
*/
protected $cache;
/**
* Default Location data.
*
* @var array
*/
protected $default_location = [
'ip' => '127.0.0.0',
'iso_code' => 'US',
'country' => 'United States',
'city' => 'New Haven',
'state' => 'CT',
'state_name' => 'Connecticut',
'postal_code' => '06510',
'lat' => 41.31,
'lon' => -72.92,
'timezone' => 'America/New_York',
'continent' => 'NA',
'currency' => 'USD',
'default' => true,
'cached' => false,
];
/**
* Create a new GeoIP instance.
*
* @param array $config
* @param CacheManager $cache
*/
public function __construct(array $config, CacheManager $cache)
{
$this->config = $config;
// Create caching instance
$this->cache = new Cache(
$cache,
$this->config('cache_tags'),
$this->config('cache_expires', 30)
);
// Set custom default location
$this->default_location = array_merge(
$this->default_location,
$this->config('default_location', [])
);
// Set IP
$this->remote_ip = $this->default_location['ip'] = $this->getClientIP();
}
/**
* Get the location from the provided IP.
*
* @param string $ip
*
* @return \Torann\GeoIP\Location
*/
public function getLocation($ip = null)
{
// Get location data
$this->location = $this->find($ip);
// Should cache location
if ($this->shouldCache($ip, $this->location)) {
$this->getCache()->set($ip, $this->location);
}
return $this->location;
}
/**
* Find location from IP.
*
* @param string $ip
*
* @return \Torann\GeoIP\Location
* @throws \Exception
*/
private function find($ip = null)
{
// Check cache for location
if ($this->config('cache', 'none') !== 'none' && $location = $this->getCache()->get($ip)) {
$location->cached = true;
return $location;
}
// If IP not set, user remote IP
$ip = $ip ?: $this->remote_ip;
// Check if the ip is not local or empty
if ($this->isValid($ip)) {
try {
// Find location
$location = $this->getService()->locate($ip);
// Set currency if not already set by the service
if (!$location->currency) {
$location->currency = $this->getCurrency($location->iso_code);
}
// Set default
$location->default = false;
return $location;
}
catch (\Exception $e) {
if ($this->config('log_failures', true) === true) {
$log = new Logger('geoip');
$log->pushHandler(new StreamHandler(storage_path('logs/geoip.log'), Logger::ERROR));
$log->addError($e);
}
}
}
return $this->getService()->hydrate($this->default_location);
}
/**
* Get the currency code from ISO.
*
* @param string $iso
*
* @return string
*/
public function getCurrency($iso)
{
if ($this->currencies === null && $this->config('include_currency', false)) {
$this->currencies = include(__DIR__ . '/Support/Currencies.php');
}
return Arr::get($this->currencies, $iso);
}
/**
* Get service instance.
*
* @return \Torann\GeoIP\Contracts\ServiceInterface
* @throws Exception
*/
public function getService()
{
if ($this->service === null) {
// Get service configuration
$config = $this->config('services.' . $this->config('service'), []);
// Get service class
$class = Arr::pull($config, 'class');
// Sanity check
if ($class === null) {
throw new Exception('The GeoIP service is not valid.');
}
// Create service instance
$this->service = app($class, [$config]);
}
return $this->service;
}
/**
* Get cache instance.
*
* @return \Torann\GeoIP\Cache
*/
public function getCache()
{
return $this->cache;
}
/**
* Get the client IP address.
*
* @return string
*/
public function getClientIP()
{
$remotes_keys = [
'HTTP_X_FORWARDED_FOR',
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR',
'HTTP_X_CLUSTER_CLIENT_IP',
];
foreach ($remotes_keys as $key) {
if ($address = getenv($key)) {
foreach (explode(',', $address) as $ip) {
if ($this->isValid($ip)) {
return $ip;
}
}
}
}
return '127.0.0.0';
}
/**
* Checks if the ip is valid.
*
* @param string $ip
*
* @return bool
*/
private function isValid($ip)
{
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)
&& !filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE)
) {
return false;
}
return true;
}
/**
* Determine if the location should be cached.
*
* @param string $ip
* @param Location $location
*
* @return bool
*/
private function shouldCache($ip = null, Location $location)
{
if ($location->default === true || $location->cached === true) {
return false;
}
switch($this->config('cache', 'none')) {
case 'all':
return true;
case 'some' && $ip === null:
return true;
}
return false;
}
/**
* Get configuration value.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function config($key, $default = null)
{
return Arr::get($this->config, $key, $default);
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Torann\GeoIP;
use Illuminate\Support\ServiceProvider;
class GeoIPServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerGeoIpService();
if ($this->app->runningInConsole()) {
$this->registerResources();
$this->registerGeoIpCommands();
}
}
/**
* Register currency provider.
*
* @return void
*/
public function registerGeoIpService()
{
$this->app->singleton('geoip', function ($app) {
return new GeoIP(
$app->config->get('geoip', []),
$app['cache']
);
});
}
/**
* Register currency resources.
*
* @return void
*/
public function registerResources()
{
if ($this->isLumen() === false) {
$this->publishes([
__DIR__ . '/../config/geoip.php' => config_path('geoip.php'),
], 'config');
}
}
/**
* Register currency commands.
*
* @return void
*/
public function registerGeoIpCommands()
{
$this->commands([
Console\Update::class,
Console\Clear::class,
]);
}
/**
* Check if package is running under Lumen app
*
* @return bool
*/
protected function isLumen()
{
return str_contains($this->app->version(), 'Lumen') === true;
}
}

197
vendor/torann/geoip/src/Location.php vendored Normal file
View File

@@ -0,0 +1,197 @@
<?php
namespace Torann\GeoIP;
use ArrayAccess;
use Illuminate\Support\Str;
use Illuminate\Support\Arr;
class Location implements ArrayAccess
{
/**
* The location's attributes
*
* @var array
*/
protected $attributes = [];
/**
* Create a new location instance.
*
* @param array $attributes
*/
public function __construct(array $attributes = [])
{
$this->attributes = $attributes;
}
/**
* Determine if the location is for the same IP address.
*
* @param string $ip
*
* @return bool
*/
public function same($ip)
{
return $this->getAttribute('ip') == $ip;
}
/**
* Set a given attribute on the location.
*
* @param string $key
* @param mixed $value
*
* @return $this
*/
public function setAttribute($key, $value)
{
$this->attributes[$key] = $value;
return $this;
}
/**
* Get an attribute from the $attributes array.
*
* @param string $key
*
* @return mixed
*/
public function getAttribute($key)
{
$value = Arr::get($this->attributes, $key);
// First we will check for the presence of a mutator for the set operation
// which simply lets the developers tweak the attribute as it is set.
if (method_exists($this, 'get' . Str::studly($key) . 'Attribute')) {
$method = 'get' . Str::studly($key) . 'Attribute';
return $this->{$method}($value);
}
return $value;
}
/**
* Return the display name of the location.
*
* @return string
*/
public function getDisplayNameAttribute()
{
return preg_replace('/^,\s/', '', "{$this->city}, {$this->state}");
}
/**
* Is the location the default.
*
* @return bool
*/
public function getDefaultAttribute($value)
{
return is_null($value) ? false : $value;
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return $this->attributes;
}
/**
* Get the location's attribute
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
return $this->getAttribute($key);
}
/**
* Set the location's attribute
*
* @param string $key
* @param mixed $value
*/
public function __set($key, $value)
{
$this->setAttribute($key, $value);
}
/**
* Determine if the given attribute exists.
*
* @param mixed $offset
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->$offset);
}
/**
* Get the value for a given offset.
*
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset)
{
return $this->$offset;
}
/**
* Set the value for a given offset.
*
* @param mixed $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value)
{
$this->$offset = $value;
}
/**
* Unset the value for a given offset.
*
* @param mixed $offset
* @return void
*/
public function offsetUnset($offset)
{
unset($this->$offset);
}
/**
* Check if the location's attribute is set
*
* @param $key
*
* @return bool
*/
public function __isset($key)
{
return array_key_exists($key, $this->attributes);
}
/**
* Unset an attribute on the location.
*
* @param string $key
* @return void
*/
public function __unset($key)
{
unset($this->attributes[$key]);
}
}

View File

@@ -0,0 +1,61 @@
<?php
namespace Torann\GeoIP\Services;
use Torann\GeoIP\GeoIP;
use Torann\GeoIP\Location;
use Illuminate\Support\Arr;
use Torann\GeoIP\Contracts\ServiceInterface;
abstract class AbstractService implements ServiceInterface
{
/**
* Driver config
*
* @var array
*/
protected $config;
/**
* Create a new service instance.
*
* @param array $config
*/
public function __construct(array $config = [])
{
$this->config = $config;
$this->boot();
}
/**
* The "booting" method of the service.
*
* @return void
*/
public function boot()
{
//
}
/**
* {@inheritdoc}
*/
public function hydrate(array $attributes = [])
{
return new Location($attributes);
}
/**
* Get configuration value.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function config($key, $default = null)
{
return Arr::get($this->config, $key, $default);
}
}

View File

@@ -0,0 +1,142 @@
<?php
namespace Torann\GeoIP\Services;
use Exception;
use Illuminate\Support\Arr;
use Torann\GeoIP\Support\HttpClient;
class IPApi extends AbstractService
{
/**
* Http client instance.
*
* @var HttpClient
*/
protected $client;
/**
* An array of continents.
*
* @var array
*/
protected $continents;
/**
* The "booting" method of the service.
*
* @return void
*/
public function boot()
{
$base = [
'base_uri' => 'http://ip-api.com/',
'headers' => [
'User-Agent' => 'Laravel-GeoIP',
],
'query' => [
'fields' => 49663,
],
];
// Using the Pro service
if ($this->config('key')) {
$base['base_uri'] = ($this->config('secure') ? 'https' : 'http') . '://pro.ip-api.com/';
$base['query']['key'] = $this->config('key');
}
$this->client = new HttpClient($base);
// Set continents
if (file_exists($this->config('continent_path'))) {
$this->continents = json_decode(file_get_contents($this->config('continent_path')), true);
}
}
/**
* {@inheritdoc}
*/
public function locate($ip)
{
// Get data from client
$data = $this->client->get('json/' . $ip);
// Verify server response
if ($this->client->getErrors() !== null) {
throw new Exception('Request failed (' . $this->client->getErrors() . ')');
}
// Parse body content
$json = json_decode($data[0]);
// Verify response status
if ($json->status !== 'success') {
throw new Exception('Request failed (' . $json->message . ')');
}
return $this->hydrate([
'ip' => $ip,
'iso_code' => $json->countryCode,
'country' => $json->country,
'city' => $json->city,
'state' => $json->region,
'state_name' => $json->regionName,
'postal_code' => $json->zip,
'lat' => $json->lat,
'lon' => $json->lon,
'timezone' => $json->timezone,
'continent' => $this->getContinent($json->countryCode),
]);
}
/**
* Update function for service.
*
* @return string
* @throws Exception
*/
public function update()
{
$data = $this->client->get('http://dev.maxmind.com/static/csv/codes/country_continent.csv');
// Verify server response
if ($this->client->getErrors() !== null) {
throw new Exception($this->client->getErrors());
}
$lines = explode("\n", $data[0]);
array_shift($lines);
$output = [];
foreach ($lines as $line) {
$arr = str_getcsv($line);
if (count($arr) < 2) {
continue;
}
$output[$arr[0]] = $arr[1];
}
// Get path
$path = $this->config('continent_path');
file_put_contents($path, json_encode($output));
return "Continent file ({$path}) updated.";
}
/**
* Get continent based on country code.
*
* @param string $code
*
* @return string
*/
private function getContinent($code)
{
return Arr::get($this->continents, $code, 'Unknown');
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Torann\GeoIP\Services;
use Exception;
use GeoIp2\Database\Reader;
use GeoIp2\Exception\AddressNotFoundException;
class MaxMindDatabase extends AbstractService
{
/**
* Service reader instance.
*
* @var \GeoIp2\Database\Reader
*/
protected $reader;
/**
* The "booting" method of the service.
*
* @return void
*/
public function boot()
{
// Copy test database for now
if (file_exists($this->config('database_path')) === false) {
copy(__DIR__ . '/../../resources/geoip.mmdb', $this->config('database_path'));
}
$this->reader = new Reader(
$this->config('database_path'),
$this->config('locales', ['en'])
);
}
/**
* {@inheritdoc}
*/
public function locate($ip)
{
$record = $this->reader->city($ip);
return $this->hydrate([
'ip' => $ip,
'iso_code' => $record->country->isoCode,
'country' => $record->country->name,
'city' => $record->city->name,
'state' => $record->mostSpecificSubdivision->isoCode,
'state_name' => $record->mostSpecificSubdivision->name,
'postal_code' => $record->postal->code,
'lat' => $record->location->latitude,
'lon' => $record->location->longitude,
'timezone' => $record->location->timeZone,
'continent' => $record->continent->code,
]);
}
/**
* Update function for service.
*
* @return string
* @throws Exception
*/
public function update()
{
if ($this->config('database_path', false) === false) {
throw new Exception('Database path not set in config file.');
}
// Get settings
$url = $this->config('update_url');
$path = $this->config('database_path');
// Get header response
$headers = get_headers($url);
if (substr($headers[0], 9, 3) != '200') {
throw new Exception('Unable to download database. ('. substr($headers[0], 13) .')');
}
// Download zipped database to a system temp file
$tmpFile = tempnam(sys_get_temp_dir(), 'maxmind');
file_put_contents($tmpFile, fopen($url, 'r'));
// Unzip and save database
file_put_contents($path, gzopen($tmpFile, 'r'));
// Remove temp file
@unlink($tmpFile);
return "Database file ({$path}) updated.";
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace Torann\GeoIP\Services;
use GeoIp2\WebService\Client;
use GeoIp2\Exception\AddressNotFoundException;
class MaxMindWebService extends AbstractService
{
/**
* Service client instance.
*
* @var \GeoIp2\WebService\Client
*/
protected $client;
/**
* The "booting" method of the service.
*
* @return void
*/
public function boot()
{
$this->client = new Client(
$this->config('user_id'),
$this->config('license_key'),
$this->config('locales', ['en'])
);
}
/**
* {@inheritdoc}
*/
public function locate($ip)
{
$record = $this->client->city($ip);
return $this->hydrate([
'ip' => $ip,
'iso_code' => $record->country->isoCode,
'country' => $record->country->name,
'city' => $record->city->name,
'state' => $record->mostSpecificSubdivision->isoCode,
'state_name' => $record->mostSpecificSubdivision->name,
'postal_code' => $record->postal->code,
'lat' => $record->location->latitude,
'lon' => $record->location->longitude,
'timezone' => $record->location->timeZone,
'continent' => $record->continent->code,
]);
}
}

View File

@@ -0,0 +1,251 @@
<?php
return [
'AD' => 'EUR',
'AE' => 'AED',
'AF' => 'AFN',
'AG' => 'XCD',
'AI' => 'XCD',
'AL' => 'ALL',
'AM' => 'AMD',
'AN' => 'ANG',
'AO' => 'AOA',
'AQ' => '',
'AR' => 'ARS',
'AS' => 'USD',
'AT' => 'EUR',
'AU' => 'AUD',
'AW' => 'AWG',
'AZ' => 'AZN',
'BA' => 'BAM',
'BB' => 'BBD',
'BD' => 'BDT',
'BE' => 'EUR',
'BF' => 'XOF',
'BG' => 'BGN',
'BH' => 'BHD',
'BI' => 'BIF',
'BJ' => 'XOF',
'BL' => 'EUR',
'BM' => 'BMD',
'BN' => 'BND',
'BO' => 'BOB',
'BR' => 'BRL',
'BS' => 'BSD',
'BT' => 'BTN',
'BV' => 'NOK',
'BW' => 'BWP',
'BY' => 'BYR',
'BZ' => 'BZD',
'CA' => 'CAD',
'CC' => 'AUD',
'CD' => 'CDF',
'CF' => 'XAF',
'CG' => 'CDF',
'CH' => 'CHF',
'CI' => 'XOF',
'CK' => 'NZD',
'CL' => 'CLP',
'CM' => 'XAF',
'CN' => 'CNY',
'CO' => 'COP',
'CR' => 'CRC',
'CU' => 'CUP',
'CV' => 'CVE',
'CW' => 'ANG',
'CX' => 'AUD',
'CY' => 'EUR',
'CZ' => 'CZK',
'DE' => 'EUR',
'DJ' => 'DJF',
'DK' => 'DKK',
'DM' => 'XCD',
'DO' => 'DOP',
'DZ' => 'DZD',
'EC' => 'USD',
'EE' => 'EUR',
'EG' => 'EGP',
'EH' => 'MAD',
'ER' => 'ERN',
'ES' => 'EUR',
'ET' => 'ETB',
'FI' => 'EUR',
'FJ' => 'FJD',
'FK' => 'FKP',
'FM' => 'USD',
'FO' => 'DKK',
'FR' => 'EUR',
'GA' => 'XAF',
'GB' => 'GBP',
'GD' => 'XCD',
'GE' => 'GEL',
'GF' => 'EUR',
'GG' => 'GGP',
'GH' => 'GHS',
'GI' => 'GIP',
'GL' => 'DKK',
'GM' => 'GMD',
'GN' => 'GNF',
'GP' => 'EUR',
'GQ' => 'XAF',
'GR' => 'EUR',
'GS' => 'GBP',
'GT' => 'GTQ',
'GU' => 'USD',
'GW' => 'XOF',
'GY' => 'GYD',
'HK' => 'HKD',
'HM' => 'AUD',
'HN' => 'HNL',
'HR' => 'HRK',
'HT' => 'HTG',
'HU' => 'HUF',
'ID' => 'IDR',
'IE' => 'EUR',
'IL' => 'ILS',
'IM' => 'IMP',
'IN' => 'INR',
'IO' => 'USD',
'IQ' => 'IQD',
'IR' => 'IRR',
'IS' => 'ISK',
'IT' => 'EUR',
'JE' => 'JEP',
'JM' => 'JMD',
'JO' => 'JOD',
'JP' => 'JPY',
'KE' => 'KES',
'KG' => 'KGS',
'KH' => 'KHR',
'KI' => 'AUD',
'KM' => 'KMF',
'KN' => 'XCD',
'KP' => 'KPW',
'KR' => 'KRW',
'KW' => 'KWD',
'KY' => 'KYD',
'KZ' => 'KZT',
'LA' => 'LAK',
'LB' => 'LBP',
'LC' => 'XCD',
'LI' => 'CHF',
'LK' => 'LKR',
'LR' => 'LRD',
'LS' => 'LSL',
'LT' => 'EUR',
'LU' => 'EUR',
'LV' => 'EUR',
'LY' => 'LYD',
'MA' => 'MAD',
'MC' => 'EUR',
'MD' => 'MDL',
'ME' => 'EUR',
'MG' => 'MGA',
'MH' => 'USD',
'MK' => 'MKD',
'ML' => 'XOF',
'MM' => 'MMK',
'MN' => 'MNT',
'MO' => 'MOP',
'MP' => 'USD',
'MQ' => 'EUR',
'MR' => 'MRO',
'MS' => 'XCD',
'MT' => 'EUR',
'MU' => 'MUR',
'MV' => 'MVR',
'MW' => 'MWK',
'MX' => 'MXN',
'MY' => 'MYR',
'MZ' => 'MZN',
'NA' => 'NAD',
'NC' => 'XPF',
'NE' => 'XOF',
'NF' => 'AUD',
'NG' => 'NGN',
'NI' => 'NIO',
'NL' => 'EUR',
'NO' => 'NOK',
'NP' => 'NPR',
'NR' => 'AUD',
'NU' => 'NZD',
'NZ' => 'NZD',
'OM' => 'OMR',
'PA' => 'PAB',
'PE' => 'PEN',
'PF' => 'XPF',
'PG' => 'PGK',
'PH' => 'PHP',
'PK' => 'PKR',
'PL' => 'PLN',
'PM' => 'EUR',
'PN' => 'GBP',
'PR' => 'USD',
'PS' => 'ILS',
'PT' => 'EUR',
'PW' => 'USD',
'PY' => 'PYG',
'QA' => 'QAR',
'RE' => 'EUR',
'RO' => 'RON',
'RS' => 'RSD',
'RU' => 'RUB',
'RW' => 'RWF',
'SA' => 'SAR',
'SB' => 'SBD',
'SC' => 'SCR',
'SD' => 'SDG',
'SE' => 'SEK',
'SG' => 'SGD',
'SH' => 'SHP',
'SI' => 'EUR',
'SJ' => 'NOK',
'SK' => 'EUR',
'SL' => 'SLL',
'SM' => 'EUR',
'SN' => 'XOF',
'SO' => 'SOS',
'SR' => 'SRD',
'SS' => 'SSP',
'ST' => 'STD',
'SV' => 'USD',
'SX' => 'ANG',
'SY' => 'SYP',
'SZ' => 'SZL',
'TC' => 'USD',
'TD' => 'XAF',
'TF' => 'EUR',
'TG' => 'XOF',
'TH' => 'THB',
'TJ' => 'TJS',
'TK' => 'NZD',
'TL' => 'USD',
'TM' => 'TMT',
'TN' => 'TND',
'TO' => 'TOP',
'TR' => 'TRY',
'TT' => 'TTD',
'TV' => 'AUD',
'TW' => 'TWD',
'TZ' => 'TZS',
'UA' => 'UAH',
'UG' => 'UGX',
'US' => 'USD',
'UY' => 'UYU',
'UZ' => 'UZS',
'VA' => 'EUR',
'VC' => 'XCD',
'VE' => 'VEF',
'VG' => 'USD',
'VI' => 'USD',
'VN' => 'VND',
'VU' => 'VUV',
'WF' => 'XPF',
'WS' => 'WST',
'XK' => 'EUR',
'YE' => 'YER',
'YT' => 'EUR',
'ZA' => 'ZAR',
'ZM' => 'ZMK',
'ZW' => 'ZWL',
];

View File

@@ -0,0 +1,245 @@
<?php
namespace Torann\GeoIP\Support;
use Illuminate\Support\Arr;
class HttpClient
{
/**
* Request configurations.
*
* @var array
**/
private $config = [
'base_uri' => '',
'headers' => [],
'query' => [],
];
/**
* Last request http status.
*
* @var int
**/
protected $http_code = 200;
/**
* Last request error string.
*
* @var string
**/
protected $errors = null;
/**
* Array containing headers from last performed request.
*
* @var array
*/
private $headers = [];
/**
* HttpClient constructor.
*
* @param array $config
*/
public function __construct(array $config = [])
{
$this->config = $config;
}
/**
* Perform a get request.
*
* @param string $url
* @param array $query
* @param array $headers
*
* @return array
*/
public function get($url, array $query = [], array $headers = [])
{
return $this->execute('GET', $this->buildGetUrl($url, $query), [], $headers);
}
/**
* Execute the curl request
*
* @param string $method
* @param string $url
* @param array $query
* @param array $headers
*
* @return array
*/
public function execute($method, $url, array $query = [], array $headers = [])
{
// Merge global and request headers
$headers = array_merge(
Arr::get($this->config, 'headers', []),
$headers
);
// Merge global and request queries
$query = array_merge(
Arr::get($this->config, 'query', []),
$query
);
$this->errors = null;
$curl = curl_init();
// Set options
curl_setopt_array($curl, [
CURLOPT_URL => $this->getUrl($url),
CURLOPT_HTTPHEADER => $headers,
CURLOPT_CONNECTTIMEOUT => 20,
CURLOPT_TIMEOUT => 90,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_HEADER => 1,
CURLINFO_HEADER_OUT => 1,
CURLOPT_VERBOSE => 1,
]);
// Setup method specific options
switch ($method) {
case 'PUT':
case 'PATCH':
case 'POST':
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $query,
]);
break;
case 'DELETE':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
default:
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
break;
}
// Make request
curl_setopt($curl, CURLOPT_HEADER, true);
$response = curl_exec($curl);
// Set HTTP response code
$this->http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Set errors if there are any
if (curl_errno($curl)) {
$this->errors = curl_error($curl);
}
// Parse body
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);
curl_close($curl);
return [$body, $this->parseHeaders($header)];
}
/**
* Check if the curl request ended up with errors
*
* @return bool
*/
public function hasErrors()
{
return is_null($this->errors) === false;
}
/**
* Get curl errors
*
* @return string
*/
public function getErrors()
{
return $this->errors;
}
/**
* Get last curl HTTP code.
*
* @return int
*/
public function getHttpCode()
{
return $this->http_code;
}
/**
* Parse string headers into array
*
* @param string $headers
*
* @return array
*/
private function parseHeaders($headers)
{
$result = [];
foreach (preg_split("/\\r\\n|\\r|\\n/", $headers) as $row) {
$header = explode(':', $row, 2);
if (count($header) == 2) {
$result[$header[0]] = trim($header[1]);
}
else {
$result[] = $header[0];
}
}
return $result;
}
/**
* Get request URL.
*
* @param string $url
*
* @return string
*/
private function getUrl($url)
{
// Check for URL scheme
if (parse_url($url, PHP_URL_SCHEME) === null) {
$url = Arr::get($this->config, 'base_uri') . $url;
}
return $url;
}
/**
* Build a GET request string.
*
* @param string $url
* @param array $query
*
* @return string
*/
private function buildGetUrl($url, array $query = [])
{
// Merge global and request queries
$query = array_merge(
Arr::get($this->config, 'query', []),
$query
);
// Append query
if ($query = http_build_query($query)) {
$url .= strpos($url, '?') ? $query : "?{$query}";
}
return $url;
}
}

View File

@@ -1,57 +0,0 @@
<?php namespace Torann\GeoIP\Console;
use Illuminate\Config\Repository;
use Illuminate\Console\Command;
use Torann\GeoIP\GeoIPUpdater;
class UpdateCommand extends Command
{
/**
* The console command name.
*
* @var string
*/
protected $name = 'geoip:update';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Update geoip database files to the latest version';
/**
* @var \Torann\GeoIP\GeoIPUpdater
*/
protected $geoIPUpdater;
/**
* Create a new console command instance.
*
* @param \Illuminate\Config\Repository $config
*/
public function __construct(Repository $config)
{
parent::__construct();
$this->geoIPUpdater = new GeoIPUpdater($config);
}
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
$result = $this->geoIPUpdater->update();
if (!$result) {
$this->error('Update failed!');
return;
}
$this->info('New update file ('.$result.') installed.');
}
}

View File

@@ -1,282 +0,0 @@
<?php namespace Torann\GeoIP;
use GeoIp2\Database\Reader;
use GeoIp2\WebService\Client;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use GeoIp2\Exception\AddressNotFoundException;
use Illuminate\Config\Repository;
use Illuminate\Session\Store as SessionStore;
class GeoIP {
/**
* The session store.
*
* @var \Illuminate\Session\Store
*/
protected $session;
/**
* Illuminate config repository instance.
*
* @var \Illuminate\Config\Repository
*/
protected $config;
/**
* Remote Machine IP address.
*
* @var float
*/
protected $remote_ip = null;
/**
* Location data.
*
* @var array
*/
protected $location = null;
/**
* Reserved IP address.
*
* @var array
*/
protected $reserved_ips = array (
array('0.0.0.0','2.255.255.255'),
array('10.0.0.0','10.255.255.255'),
array('127.0.0.0','127.255.255.255'),
array('169.254.0.0','169.254.255.255'),
array('172.16.0.0','172.31.255.255'),
array('192.0.2.0','192.0.2.255'),
array('192.168.0.0','192.168.255.255'),
array('255.255.255.0','255.255.255.255'),
);
/**
* Default Location data.
*
* @var array
*/
protected $default_location = array (
"ip" => "127.0.0.0",
"isoCode" => "US",
"country" => "United States",
"city" => "New Haven",
"state" => "CT",
"postal_code" => "06510",
"lat" => 41.31,
"lon" => -72.92,
"timezone" => "America/New_York",
"continent" => "NA",
"default" => true,
);
/**
* Create a new GeoIP instance.
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Session\Store $session
*/
public function __construct(Repository $config, SessionStore $session)
{
$this->config = $config;
$this->session = $session;
// Set custom default location
$this->default_location = array_merge(
$this->default_location,
$this->config->get('geoip.default_location', array())
);
// Set IP
$this->remote_ip = $this->default_location['ip'] = $this->getClientIP();
}
/**
* Save location data in the session.
*
* @return void
*/
function saveLocation()
{
$this->session->set('geoip-location', $this->location);
}
/**
* Get location from IP.
*
* @param string $ip Optional
* @return array
*/
public function getLocation($ip = null)
{
// Get location data
$this->location = $this->find($ip);
// Save user's location
if ($ip === null) {
$this->saveLocation();
}
return $this->location;
}
/**
* Find location from IP.
*
* @param string $ip Optional
* @return array
* @throws \Exception
*/
private function find($ip = null)
{
// Check Session
if ($ip === null && $position = $this->session->get('geoip-location')) {
return $position;
}
// If IP not set, user remote IP
if ($ip === null) {
$ip = $this->remote_ip;
}
// Check if the ip is not local or empty
if ($this->checkIp($ip)) {
// Get service name
$service = 'locate_'.$this->config->get('geoip.service');
// Check for valid service
if (! method_exists($this, $service)) {
throw new \Exception("GeoIP Service not support or setup.");
}
return $this->$service($ip);
}
return $this->default_location;
}
private $maxmind;
/**
* Maxmind Service.
*
* @param string $ip
* @return array
*/
private function locate_maxmind($ip)
{
$settings = $this->config->get('geoip.maxmind');
if (empty($this->maxmind)) {
if ($settings['type'] === 'web_service') {
$this->maxmind = new Client($settings['user_id'], $settings['license_key']);
}
else {
$this->maxmind = new Reader($settings['database_path']);
}
}
try {
$record = $this->maxmind->city($ip);
$location = array(
"ip" => $ip,
"isoCode" => $record->country->isoCode,
"country" => $record->country->name,
"city" => $record->city->name,
"state" => $record->mostSpecificSubdivision->isoCode,
"postal_code" => $record->postal->code,
"lat" => $record->location->latitude,
"lon" => $record->location->longitude,
"timezone" => $record->location->timeZone,
"continent" => $record->continent->code,
"default" => false,
);
}
catch (AddressNotFoundException $e)
{
$location = $this->default_location;
$logFile = 'geoip';
$log = new Logger($logFile);
$log->pushHandler(new StreamHandler(storage_path("logs/{$logFile}.log"), Logger::ERROR));
$log->addError($e);
}
unset($record);
return $location;
}
/**
* Get the client IP address.
*
* @return string
*/
private function getClientIP()
{
if (getenv('HTTP_CLIENT_IP')) {
$ipaddress = getenv('HTTP_CLIENT_IP');
}
else if (getenv('HTTP_X_FORWARDED_FOR')) {
$ipaddress = getenv('HTTP_X_FORWARDED_FOR');
}
else if (getenv('HTTP_X_FORWARDED')) {
$ipaddress = getenv('HTTP_X_FORWARDED');
}
else if (getenv('HTTP_FORWARDED_FOR')) {
$ipaddress = getenv('HTTP_FORWARDED_FOR');
}
else if (getenv('HTTP_FORWARDED')) {
$ipaddress = getenv('HTTP_FORWARDED');
}
else if (getenv('REMOTE_ADDR')) {
$ipaddress = getenv('REMOTE_ADDR');
}
else if (isset($_SERVER['REMOTE_ADDR'])) {
$ipaddress = $_SERVER['REMOTE_ADDR'];
}
else {
$ipaddress = '127.0.0.0';
}
return $ipaddress;
}
/**
* Checks if the ip is not local or empty.
*
* @return bool
*/
private function checkIp($ip)
{
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$longip = ip2long($ip);
if (! empty($ip)) {
foreach ($this->reserved_ips as $r) {
$min = ip2long($r[0]);
$max = ip2long($r[1]);
if ($longip >= $min && $longip <= $max) {
return false;
}
}
return true;
}
} else if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
return true;
}
return false;
}
}

View File

@@ -1,14 +0,0 @@
<?php namespace Torann\GeoIP;
use Illuminate\Support\Facades\Facade;
class GeoIPFacade extends Facade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor() { return 'geoip'; }
}

View File

@@ -1,57 +0,0 @@
<?php namespace Torann\GeoIP;
use Illuminate\Support\ServiceProvider;
use Torann\GeoIP\Console\UpdateCommand;
class GeoIPServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../../config/geoip.php' => config_path('geoip.php'),
]);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// Register providers.
$this->app['geoip'] = $this->app->share(function($app)
{
return new GeoIP($app['config'], $app["session.store"]);
});
$this->app['command.geoip.update'] = $this->app->share(function ($app)
{
return new UpdateCommand($app['config']);
});
$this->commands(['command.geoip.update']);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('geoip', 'command.geoip.update');
}
}

View File

@@ -1,62 +0,0 @@
<?php namespace Torann\GeoIP;
use GuzzleHttp\Client as Client;
use Illuminate\Config\Repository;
class GeoIPUpdater
{
/**
* @var array
*/
protected $config;
/**
* @var Client
*/
protected $client;
/**
* @param array $config
*/
public function __construct(Repository $config)
{
$this->config = $config;
}
/**
* Main update function.
*
* @return bool|string
*/
public function update()
{
if ($this->config->get('geoip.maxmind.database_path', false)) {
return $this->updateMaxMindDatabase();
}
return false;
}
/**
* Update function for max mind database.
*
* @return string
*/
protected function updateMaxMindDatabase()
{
$maxMindDatabaseUrl = $this->config->get('geoip.maxmind.update_url');
$databasePath = $this->config->get('geoip.maxmind.database_path');
// Download zipped database to a system temp file
$tmpFile = tempnam(sys_get_temp_dir(), 'maxmind');
file_put_contents($tmpFile, fopen($maxMindDatabaseUrl, 'r'));
// Unzip and save database
file_put_contents($databasePath, gzopen($tmpFile, 'r'));
// Remove temp file
@unlink($tmpFile);
return $databasePath;
}
}

View File

@@ -1,55 +0,0 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Service
|--------------------------------------------------------------------------
|
| Current only supports 'maxmind'.
|
*/
'service' => 'maxmind',
/*
|--------------------------------------------------------------------------
| Services settings
|--------------------------------------------------------------------------
|
| Service specific settings.
|
*/
'maxmind' => array(
'type' => env('GEOIP_DRIVER', 'database'), // database or web_service
'user_id' => env('GEOIP_USER_ID'),
'license_key' => env('GEOIP_LICENSE_KEY'),
'database_path' => storage_path('app/geoip.mmdb'),
'update_url' => 'https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz',
),
/*
|--------------------------------------------------------------------------
| Default Location
|--------------------------------------------------------------------------
|
| Return when a location is not found.
|
*/
'default_location' => array (
"ip" => "127.0.0.0",
"isoCode" => "US",
"country" => "United States",
"city" => "New Haven",
"state" => "CT",
"postal_code" => "06510",
"lat" => 41.31,
"lon" => -72.92,
"timezone" => "America/New_York",
"continent" => "NA",
),
);

19
vendor/torann/geoip/src/helpers.php vendored Normal file
View File

@@ -0,0 +1,19 @@
<?php
if (!function_exists('geoip')) {
/**
* Get the location of the provided IP.
*
* @param string $ip
*
* @return \Torann\GeoIP\GeoIP|string
*/
function geoip($ip = null)
{
if (is_null($ip)) {
return app('geoip');
}
return app('geoip')->getLocation($ip);
}
}