first commit

This commit is contained in:
DESKTOP-GBA0BK8\Admin
2023-04-08 12:19:53 -04:00
commit 7c8c8b1c76
4586 changed files with 2050693 additions and 0 deletions
@@ -0,0 +1,128 @@
<?php
/**
Each datasource has:
- An id, name & description
- A reader that can generate Maxmind GeoIP records.
- (optional) Configuration options
- (optional) Data Source Information (only shown for
- activate / deactivate when activated / deactivated by the user
For future compatibility:
Each data source may not rely on the fact that it is the "currently chosen" source. There may be several sources that are "activated" and then used in a fallback manner.
In practise this means that wordpress filters should be used only in conjunction of checks like
if ($record->extra->source == $this->getId()) { ...
*/
namespace YellowTree\GeoipDetect\DataSources {
abstract class AbstractDataSource {
public function __construct() {}
abstract public function getId();
public function getLabel() { return ''; }
public function getDescriptionHTML() { return ''; }
public function getStatusInformationHTML() { return ''; }
public function getParameterHTML() { return ''; }
public function saveParameters($post) { }
public function getShortLabel() { return $this->getLabel(); }
public function activate() { }
public function deactivate() { }
public function uninstall() {}
public function getReader($locales = array('en'), $options = array()) { return null; }
public function isWorking() { return false; }
}
/**
* This Class extends the Maxmind City with more attributes.
*
* @property bool $isEmpty (Wordpress Plugin) If the record is empty or contains any data.
*
* @property \YellowTree\GeoipDetect\DataSources\ExtraInformation $extra (Wordpress Plugin) Extra Information added by the GeoIP Detect plugin
*/
class City extends \GeoIp2\Model\Insights {
/**
* @ignore
*/
protected $extra;
/**
* @ignore
*/
public function __construct($raw, $locales) {
parent::__construct($raw, $locales);
$this->extra = new ExtraInformation($this->get('extra'));
}
public function __get($attr) {
if ($attr == 'isEmpty')
return $this->raw['is_empty'];
else
return parent::__get($attr);
}
}
/**
* @property string $source Id of the source that this record is originating from.
*
* @property int $cached 0 if not cached, else Unix Timestamp when it was written to the cache.
*
* @property string $error Error message if one occured during lookup. If multiple errors, they are seperated by \n
*/
class ExtraInformation extends \GeoIp2\Record\AbstractRecord {
/**
* @ignore
*/
protected $validAttributes = array('source', 'cached', 'error', 'original', 'flag', 'tel');
}
interface ReaderInterface extends \GeoIp2\ProviderInterface {
/**
* Closes the database and returns the resources to the system.
*/
public function close();
}
abstract class AbstractReader implements \YellowTree\GeoipDetect\DataSources\ReaderInterface {
protected $options;
public function __construct($options = array()) {
$this->options = $options;
}
public function city($ip) {
throw new \BadMethodCallException('This datasource does not provide data for city()');
}
public function country($ip) {
throw new \BadMethodCallException('This datasource does not provide data for country()');
}
public function close() {
}
}
} // end namespace
namespace { // global namespace
function geoip_detect2_register_source($source) {
$registry = \YellowTree\GeoipDetect\DataSources\DataSourceRegistry::getInstance();
$registry->register($source);
}
function geoip_detect2_is_source_active($sourceId) {
$registry = \YellowTree\GeoipDetect\DataSources\DataSourceRegistry::getInstance();
return $sourceId == $registry->getCurrentSource();
}
}
@@ -0,0 +1,259 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
namespace YellowTree\GeoipDetect\DataSources\Auto;
use YellowTree\GeoipDetect\DataSources\Manual\ManualDataSource;
define('GEOIP_DETECT_DATA_UPDATE_FILENAME', 'GeoLite2-City.mmdb');
class AutoDataSource extends ManualDataSource
{
public function getId() { return 'auto'; }
public function getLabel() { return __('Automatic download & update of Maxmind GeoIP Lite City', 'geoip-detect'); }
public function getShortLabel() { return sprintf(__('%s (updated monthly)', 'geoip-detect'), parent::getShortLabel()); }
public function getDescriptionHTML() { return __('(License: Creative Commons Attribution-ShareAlike 3.0 Unported. See <a href="https://github.com/yellowtree/wp-geoip-detect/wiki/FAQ#the-maxmind-lite-databases-are-licensed-creative-commons-sharealike-attribution-when-do-i-need-to-give-attribution" target="_blank">Licensing FAQ</a> for more details.)', 'geoip-detect'); }
public function getStatusInformationHTML() {
$html = parent::getStatusInformationHTML();
$date_format = get_option('date_format') . ' ' . get_option('time_format');
$rescheduled = '';
$next_cron_update = wp_next_scheduled( 'geoipdetectupdate' );
if ($next_cron_update === false) {
$rescheduled = ' ' . __('(Was rescheduled just now)', 'geoip-detect');
$this->set_cron_schedule();
$next_cron_update = wp_next_scheduled( 'geoipdetectupdate' );
}
$html .= '<br />' . sprintf(__('Next update: %s', 'geoip-detect'), $next_cron_update !== false ? date_i18n($date_format, $next_cron_update) : __('Never', 'geoip-detect'));
$html .= $rescheduled;
return $html;
}
public function getParameterHTML() {
$text_update = __('Update now', 'geoip-detect');
$nonce_field = wp_nonce_field( 'geoip_detect_update' );
$html = <<<HTML
<form method="post" action="#">
$nonce_field
<input type="hidden" name="action" value="update" />
<input type="submit" class="button button-secondary" value="$text_update" />
</form>
HTML;
return $html;
}
public function saveParameters($post) {}
public function __construct() {
parent::__construct();
add_action('geoipdetectupdate', array($this, 'hook_cron'), 10, 1);
add_action('plugins_loaded', array($this, 'on_plugins_loaded'));
}
public function on_plugins_loaded() {
if (!defined('GEOIP_DETECT_AUTO_UPDATE_DEACTIVATED'))
define('GEOIP_DETECT_AUTO_UPDATE_DEACTIVATED', false);
}
public function maxmindGetFilename() {
$data_filename = $this->maxmindGetUploadFilename();
if (!is_readable($data_filename))
$data_filename = '';
$data_filename = apply_filters('geoip_detect_get_abs_db_filename', $data_filename);
return $data_filename;
}
protected function maxmindGetUploadFilename() {
$upload_dir = wp_upload_dir();
$dir = $upload_dir['basedir'];
$filename = $dir . '/' . GEOIP_DETECT_DATA_UPDATE_FILENAME;
return $filename;
}
protected function download_url($url, $modified = 0) {
// Similar to wordpress download_url, but with custom UA
$url_filename = basename( parse_url( $url, PHP_URL_PATH ) );
$tmpfname = wp_tempnam( $url_filename );
if ( ! $tmpfname )
return new \WP_Error('http_no_file', __('Could not create temporary file.', 'geoip-detect'));
$headers = array();
$headers['User-Agent'] = GEOIP_DETECT_USER_AGENT;
if ($modified) {
$headers['If-Modified-Since'] = date('r', $modified);
}
$response = wp_safe_remote_get( $url, array('timeout' => 300, 'stream' => true, 'filename' => $tmpfname, 'headers' => $headers ) );
$http_response_code = wp_remote_retrieve_response_code( $response );
if (304 === $http_response_code) {
return new \WP_Error( 'http_304', __('It has not changed since the last update.', 'geoip-detect') );
}
if (is_wp_error( $response ) || 200 != $http_response_code) {
unlink($tmpfname);
$body = wp_remote_retrieve_body($response);
return new \WP_Error( 'http_404', $http_response_code . ': ' . trim( wp_remote_retrieve_response_message( $response ) ) . ' ' . $body );
}
return $tmpfname;
}
public function maxmindUpdate()
{
require_once(ABSPATH.'/wp-admin/includes/file.php');
$download_url = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz';
//$download_url = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz';
$download_url = apply_filters('geoip_detect2_download_url', $download_url);
$outFile = $this->maxmindGetUploadFilename();
$modified = 0;
if (\is_readable($outFile)) {
$modified = filemtime($outFile);
}
// Check if existing download should be resumed
$tmpFile = get_option('geoip-detect-auto_downloaded_file');
if (!$tmpFile || !file_exists($tmpFile)) {
// Download file
$tmpFile = $this->download_url($download_url, $modified);
}
if (is_wp_error($tmpFile)) {
return $tmpFile->get_error_message();
}
update_option('geoip-detect-auto_downloaded_file', $tmpFile);
// Unpack tar.gz
$ret = $this->unpackArchive($tmpFile, $outFile);
if (is_string($ret)) {
return $ret;
}
if (!is_readable($outFile)) {
return 'Something went wrong: the unpacked file cannot be found.';
}
update_option('geoip-detect-auto_downloaded_file', '');
unlink($tmpFile);
return true;
}
// Ungzip File
protected function unpackArchive($downloadedFilename, $outFile) {
if (!is_readable($downloadedFilename))
return __('Downloaded file could not be opened for reading.', 'geoip-detect');
if (!\is_writable(dirname($outFile)))
return sprintf(__('Database could not be written (%s).', 'geoip-detect'), $outFile);
$phar = new \PharData( $downloadedFilename );
$outDir = get_temp_dir() . 'geoip-detect/';
global $wp_filesystem;
if (!$wp_filesystem) {
\WP_Filesystem(false, get_temp_dir());
}
if (\is_dir($outDir)) {
$wp_filesystem->rmdir($outDir, true);
}
mkdir($outDir);
$phar->extractTo($outDir, null, true);
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($outDir));
$inFile = '';
foreach($files as $file) {
if (!$file->isDir() && mb_substr($file->getFilename(), -5) == '.mmdb') {
$inFile = $file->getPathname();
break;
}
}
if (!\is_readable($inFile))
return __('Downloaded file could not be opened for reading.', 'geoip-detect');
$ret = copy($inFile, $outFile);
if (!$ret)
return sprintf(__('Downloaded file could not write or overwrite %s.', 'geoip-detect'), $outFile);
$wp_filesystem->rmdir($outDir, true);
return true;
}
public function hook_cron() {
/**
* Filter:
* Cron has fired.
* Find out if file should be updated now.
*
* @param $do_it False if deactivated by define
* @param $immediately_after_activation True if this is fired because the plugin was recently activated (deprecated, will now always be false)
*/
$do_it = apply_filters('geoip_detect_cron_do_update', !GEOIP_DETECT_AUTO_UPDATE_DEACTIVATED, false);
$this->schedule_next_cron_run();
if ($do_it)
$this->maxmindUpdate();
}
public function set_cron_schedule()
{
$next = wp_next_scheduled( 'geoipdetectupdate' );
if ( $next === false ) {
$this->schedule_next_cron_run();
}
}
public function schedule_next_cron_run() {
// Try to update every 1-2 weeks
$next = time() + WEEK_IN_SECONDS;
$next += mt_rand(1, WEEK_IN_SECONDS);
wp_schedule_single_event($next, 'geoipdetectupdate');
}
public function activate() {
$this->set_cron_schedule();
}
public function deactivate()
{
wp_clear_scheduled_hook('geoipdetectupdate');
}
public function uninstall() {
// Delete the automatically downloaded file, if it exists
$filename = $this->maxmindGetFilename();
if ($filename) {
unlink($filename);
}
}
}
geoip_detect2_register_source(new AutoDataSource());
@@ -0,0 +1,158 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
namespace YellowTree\GeoipDetect\DataSources\Header;
use YellowTree\GeoipDetect\DataSources\AbstractDataSource;
class HeaderReader extends \YellowTree\GeoipDetect\DataSources\AbstractReader {
protected $providers = array(
'aws' => 'Amazon AWS CloudFront',
'cloudflare' => 'Cloudflare',
);
public function country($ip) {
$r = array();
$isoCode = '';
switch ($this->options['provider']) {
case 'aws':
if (isset($_SERVER['CloudFront-Viewer-Country'])) {
$isoCode = $_SERVER['CloudFront-Viewer-Country'];
}
break;
case 'cloudflare';
if (isset($_SERVER["HTTP_CF_IPCOUNTRY"])) {
$isoCode = $_SERVER["HTTP_CF_IPCOUNTRY"];
if ($isoCode == 'xx' /* not a country / unknown */)
$isoCode = '';
}
break;
}
$country = '';
if (!$isoCode) {
return null;
}
$r['country']['iso_code'] = strtoupper($isoCode);
$r['traits']['ip_address'] = $ip;
$record = new \GeoIp2\Model\City($r, array('en'));
return $record;
}
}
class HeaderDataSource extends AbstractDataSource {
public function getId() { return 'header'; }
public function getLabel() { return __('Special Hosting Providers (Cloudflare, Amazon AWS CloudFront)', 'geoip-detect'); }
public function getDescriptionHTML() { return __('These servers already do geodetection, but only of the visitor\'s country.', 'geoip-detect'); }
public function getStatusInformationHTML() {
$provider = get_option('geoip-detect-header-provider');
$html = '';
$link = '';
if ($provider == 'cloudflare') {
$link = 'https://support.cloudflare.com/hc/en-us/articles/200168236-What-does-CloudFlare-IP-Geolocation-do-';
} elseif ($provider == 'aws') {
$link = 'https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/';
}
if ($link)
$html = sprintf(__('This needs to be enabled in the admin panel: see <a href="%s">Help</a>.', 'geoip-detect'), $link);
return $html;
}
public function getParameterHTML() {
$provider = get_option('geoip-detect-header-provider');
$checked_cloudflare = $provider == 'cloudflare' ? 'checked' : '';
$checked_aws = $provider == 'aws' ? 'checked' : '';
$label = __('Which Hosting Provider:', 'geoip-detect');
$html = <<<HTML
<p>$label<br>
<label><input type="radio" name="options_header[provider]" value="cloudflare" $checked_cloudflare /> Cloudflare</label>
<label><input type="radio" name="options_header[provider]" value="aws" $checked_aws /> Amazon AWS CloudFront</label>
</p>
<br />
HTML;
return $html;
}
public function saveParameters($post) {
$message = '';
$value = isset($post['options_header']['provider']) ? $post['options_header']['provider'] : '';
if (!empty($value)) {
update_option('geoip-detect-header-provider', $value);
}
return $message;
}
public function getShortLabel() {
$provider = get_option('geoip-detect-header-provider');
$labels = array(
'' => __('None', 'geoip-detect'),
'aws' => 'Amazon AWS CloudFront',
'cloudflare' => 'Cloudflare',
);
if (!isset($labels[$provider]))
$provider = '';
$html = __('Hosting Provider:', 'geoip-detect') . ' ' . $labels[$provider];
return $html;
}
public function getReader($locales = array('en'), $options = array()) {
$reader = null;
$provider = get_option('geoip-detect-header-provider');
if ($provider) {
try {
$reader = new HeaderReader( array(
'provider' => $provider,
) );
} catch ( \Exception $e ) {
if (WP_DEBUG)
echo printf(__('Error while creating reader for "%s": %s', 'geoip-detect'), $filename, $e->getMessage ());
}
}
return $reader;
}
public function isWorking() {
$working = (bool) get_option('geoip-detect-header-provider');
return $working;
}
}
geoip_detect2_register_source(new HeaderDataSource());
@@ -0,0 +1,111 @@
<?php
namespace YellowTree\GeoipDetect\DataSources\HostInfo;
use YellowTree\GeoipDetect\DataSources\AbstractDataSource;
use YellowTree\GeoipDetect\DataSources\DataSourceRegistry;
class Reader implements \YellowTree\GeoipDetect\DataSources\ReaderInterface {
const URL = 'http://api.hostip.info/get_json.php?ip=';
protected $options;
function __construct($options) {
$default_options = array(
'timeout' => 1,
);
$this->options = $options + $default_options;
}
public function city($ip) {
if (!geoip_detect_is_ip($ip, true))
throw new \Exception('The Hostip.info-Database only contains IPv4 adresses.');
$data = $this->api_call($ip);
if (!$data)
return null;
$r = array();
$r['traits']['original'] = $data;
if ($data['country_name'])
$r['country']['names'] = array('en' => $data['country_name']);
if ($data['country_code'])
$r['country']['iso_code'] = strtoupper($data['country_code']);
if ($data['city']) {
$r['city']['names'] = array('en' => $data['city']);
}
$r['traits']['ip_address'] = $ip;
$record = new \GeoIp2\Model\City($r, array('en'));
return $record;
}
public function country($ip) {
return $this->city($ip); // too much info shouldn't hurt ...
}
public function close() {
}
private function api_call($ip) {
try {
// Setting timeout limit to speed up sites
$context = stream_context_create(
array(
'http' => array(
'timeout' => $this->options['timeout'],
),
)
);
// Using @file... to supress errors
// Example output: {"country_name":"UNITED STATES","country_code":"US","city":"Aurora, TX","ip":"12.215.42.19"}
$body = @file_get_contents(self::URL . $ip, false, $context);
$data = json_decode($body);
$hasInfo = false;
if ($data) {
$data = get_object_vars($data);
foreach ($data as $key => &$value) {
if (stripos($value, '(unknown') !== false)
$value = '';
if (stripos($value, '(private') !== false)
$value = '';
if ($key == 'country_code' && $value == 'XX')
$value = '';
}
$hasInfo = $data['country_name'] || $data['country_code'] || $data['city'];
}
if ($hasInfo)
return $data;
return null;
} catch (\Exception $e) {
// If the API isn't available, we have to do this
return null;
}
}
}
class HostInfoDataSource extends AbstractDataSource {
public function getId() { return 'hostinfo'; }
public function getLabel() { return __('HostIP.info Web-API', 'geoip-detect'); }
public function getDescriptionHTML() { return __('Free (Licence: GPL)<br />(only English names, does only have the following fields: country name, country ID and city name)', 'geoip-detect'); }
public function getStatusInformationHTML() { return __('You can choose a Maxmind database below.', 'geoip-detect'); }
public function getParameterHTML() { return ''; }
public function getReader($locales = array('en'), $options = array()) { return new Reader($options); }
public function isWorking() { return true; }
}
geoip_detect2_register_source(new HostInfoDataSource());
@@ -0,0 +1,242 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
namespace YellowTree\GeoipDetect\DataSources\Ipstack;
use YellowTree\GeoipDetect\DataSources\AbstractDataSource;
class Reader implements \YellowTree\GeoipDetect\DataSources\ReaderInterface {
const URL = 'api.ipstack.com/';
protected $options = array();
protected $params = array();
function __construct($params, $locales, $options) {
$this->params= $params;
$this->params['language'] = reset($locales);
if (empty($this->params['language'])) {
$this->params['language'] = 'en';
}
$default_options = array(
'timeout' => 1,
);
$this->options = $options + $default_options;
}
protected function locales($locale, $value) {
$locales = array('en' => $value);
if ($locale != 'en') {
$locales[$locale] = $value;
}
return $locales;
}
public function city($ip) {
$data = $this->api_call($ip);
if (!$data)
return null;
$r = array();
$r['extra']['original'] = $data;
if (isset($data['success']) && $data['success'] === false) {
throw new \RuntimeException($data['error']['info']);
// Example error:
/* @see https://ipstack.com/documentation#errors
{
"success": false,
"error": {
"code": 104,
"type": "monthly_limit_reached",
"info": "Your monthly API request volume has been reached. Please upgrade your plan."
}
}
*/
}
$locale = $this->params['language'];
if (!empty($data['continent_name']))
$r['continent']['names'] = $this->locales($locale, $data['continent_name']);
if (!empty($data['continent_code']))
$r['continent']['code'] = strtoupper($data['continent_code']);
if (!empty($data['country_name']))
$r['country']['names'] = $this->locales($locale, $data['country_name']);
if (!empty($data['country_code']))
$r['country']['iso_code'] = strtoupper($data['country_code']);
if (!empty($data['region_code'])) {
$r['subdivisions'][0] = array(
'iso_code' => $data['region_code'],
'names' => $this->locales($locale, $data['region_name']),
);
}
if (!empty($data['city']))
$r['city']['names'] = $this->locales($locale, $data['city']);
if (!empty($data['latitude']))
$r['location']['latitude'] = $data['latitude'];
if (!empty($data['longitude']))
$r['location']['longitude'] = $data['longitude'];
if (isset($data['is_eu']))
$r['country']['is_in_european_union'] = $data['is_eu'];
if (isset($data['timezone']['id']))
$r['location']['time_zone'] = $data['timezone']['id'];
if (isset($data['connection']['asn']))
$r['traits']['autonomous_system_number'] = $data['connection']['asn'];
if (isset($data['connection']['isp']))
$r['traits']['isp'] = $data['connection']['isp'];
if (isset($data['security']['is_proxy']))
$r['traits']['is_anonymous_vpn'] = $data['security']['is_proxy'] && $data['security']['proxy_type'] == 'vpn';
if (isset($data['security']['is_tor']))
$r['traits']['is_tor_exit_node'] = $data['security']['is_tor'];
if (!empty($data['location']['country_flag_emoji']))
$r['extra']['flag'] = strtoupper($data['location']['country_flag_emoji']);
$r['traits']['ip_address'] = $ip;
$record = new \GeoIp2\Model\City($r, array('en'));
return $record;
}
public function country($ip) {
return $this->city($ip); // too much info shouldn't hurt ...
}
public function close() {
}
private function build_url($ip) {
$url = $this->params['ssl'] ? 'https' : 'http';
$url .= '://' . self::URL . $ip;
$params = [
'access_key' => $this->params['key'],
'language' => $this->params['language'],
];
return $url . '?' . \http_build_query($params);
}
private function api_call($ip) {
try {
// Setting timeout limit to speed up sites
$context = stream_context_create(
array(
'http' => array(
'timeout' => $this->options['timeout'],
),
)
);
// Using @file... to supress errors
// Example output: {"country_name":"UNITED STATES","country_code":"US","city":"Aurora, TX","ip":"12.215.42.19"}
$body = @file_get_contents($this->build_url($ip), false, $context);
$data = json_decode($body, true);
return $data;
} catch (\Exception $e) {
// If the API isn't available, we have to do this
throw $e;
return null;
}
}
}
class IpstackSource extends AbstractDataSource {
protected $params = array();
public function __construct() {
$this->params['key'] = get_option('geoip-detect-ipstack_key', '');
$this->params['ssl'] = get_option('geoip-detect-ipstack_ssl', 0);
}
public function getId() { return 'ipstack'; }
public function getLabel() { return __('Ipstack Web-API', 'geoip-detect'); }
public function getDescriptionHTML() { return __('<a href="https://ipstack.com/">Ipstack</a>', 'geoip-detect'); }
public function getStatusInformationHTML() {
$html = '';
$html .= \sprintf(__('SSL: %s', 'geoip-detect'), $this->params['ssl'] ? __('Enabled', 'geoip-detect') : __('Disabled', 'geoip-detect')) . '<br />';
if (!$this->isWorking())
$html .= '<div class="geoip_detect_error">' . __('Ipstack only works with an API key.', 'geoip-detect') . '</div>';
return $html;
}
public function getParameterHTML() {
$label_key = __('API Access Key:', 'geoip-detect');
$label_ssl = __('Access the API via SSL:', 'geoip-detect');
$key = esc_attr($this->params['key']);
$html = <<<HTML
$label_key <input type="text" autocomplete="off" size="20" name="options_ipstack[key]" value="$key" /><br />
$label_ssl <select name="options_ipstack[ssl]">
HTML;
$html .= '<option value="0" ' . (!$this->params['ssl'] ? ' selected="selected"' : '') . '">' . __('HTTP (without encryption, not GDPR-compatible)', 'geoip-detect') . '</option>';
$html .= '<option value="1" ' . ($this->params['ssl'] ? ' selected="selected"' : '') . '">' . __('HTTPS (with encryption - paid plans only)', 'geoip-detect') . '</option>';
$html .= '</select>';
return $html;
}
public function saveParameters($post) {
$message = '';
if (isset($post['options_ipstack']['key'])) {
update_option('geoip-detect-ipstack_key', $post['options_ipstack']['key']);
$this->params['key']= $post['options_ipstack']['key'];
}
if (isset($post['options_ipstack']['ssl'])) {
$ssl = (int) $post['options_ipstack']['ssl'];
update_option('geoip-detect-ipstack_ssl', $ssl);
$this->params['ssl'] = $post['options_ipstack']['ssl'];
}
if (geoip_detect2_is_source_active('ipstack') && !$this->isWorking())
$message .= __('Ipstack only works with an API key.', 'geoip-detect');
return $message;
}
public function getReader($locales = array('en'), $options = array()) {
return new Reader($this->params, $locales, $options);
}
public function isWorking() {
return !empty($this->params['key']);
}
}
geoip_detect2_register_source(new IpstackSource());
@@ -0,0 +1,180 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
namespace YellowTree\GeoipDetect\DataSources\Manual;
use YellowTree\GeoipDetect\DataSources\AbstractDataSource;
define('GEOIP_DETECT_DATA_FILENAME', 'GeoLite2-City.mmdb');
class ManualDataSource extends AbstractDataSource {
public function getId() { return 'manual'; }
public function getLabel() { return __('Manual download & update of a Maxmind City or Country database', 'geoip-detect'); }
public function getDescriptionHTML() { return __('<a href="http://dev.maxmind.com/geoip/geoip2/geolite2/" target="_blank">Free version</a> - <a href="https://www.maxmind.com/en/geoip2-country-database" target="_blank">Commercial Version</a>', 'geoip-detect'); }
public function getStatusInformationHTML() {
$built = $last_update = 0;
$html = array();
$date_format = get_option('date_format') . ' ' . get_option('time_format');
$file = $this->maxmindGetFilename();
if (!$file)
return '<b>' . __('No Maxmind database found.', 'geoip-detect') . '</b>';
$relative_file = geoip_detect_get_relative_path(ABSPATH, $file);
$html[] = sprintf(__('Database file: %s', 'geoip-detect'), $relative_file);
$reader = $this->getReader();
if ($reader) {
$metadata = $reader->metadata();
$built = $metadata->buildEpoch;
$last_update = is_readable($file) ? filemtime($file) : '';
$html[] = sprintf(__('Last updated: %s', 'geoip-detect'), $last_update ? date_i18n($date_format, $last_update) : __('Never', 'geoip-detect'));
$html[] = sprintf(__('Database data from: %s', 'geoip-detect'), date_i18n($date_format, $built) );
}
return implode('<br>', $html);
}
public function getParameterHTML() {
$manual_file = esc_attr(get_option('geoip-detect-manual_file'));
$current_value = '';
if ( get_option('geoip-detect-manual_file_validated') &&
get_option('geoip-detect-manual_file') != get_option('geoip-detect-manual_file_validated') &&
ABSPATH . get_option('geoip-detect-manual_file') != get_option('geoip-detect-manual_file_validated')
) {
$current_value = '<br >' . sprintf(__('Current value: %s', 'geoip-detect'), get_option('geoip-detect-manual_file_validated'));
}
$label = __('Filepath to mmdb-file:', 'geoip-detect');
$desc = __('e.g. wp-content/uploads/GeoLite2-Country.mmdb or absolute filepath', 'geoip-detect');
$html = <<<HTML
<p>$label <input type="text" size="40" name="options_manual[manual_file]" value="$manual_file" /></p>
<span class="detail-box">$desc $current_value</span>
<br />
HTML;
return $html;
}
public function saveParameters($post) {
$message = '';
$file = isset($post['options_manual']['manual_file']) ? $post['options_manual']['manual_file'] : '';
if (!empty($file)) {
update_option('geoip-detect-manual_file', $file);
$validated_filename = self::maxmindValidateFilename($file);
if (empty($validated_filename)) {
$message .= __('The manual datafile has not been found or is not a mmdb-File. ', 'geoip-detect');
} else {
update_option('geoip-detect-manual_file_validated', $validated_filename);
}
}
return $message;
}
public function getShortLabel() { return $this->maxmindGetFileDescription(); }
public function getReader($locales = array('en'), $options = array()) {
$reader = null;
$data_file = $this->maxmindGetFilename();
if ($data_file) {
try {
$reader = new \GeoIp2\Database\Reader ( $data_file, $locales );
} catch ( \Exception $e ) {
if (WP_DEBUG)
printf(__('Error while creating reader for "%s": %s', 'geoip-detect'), $data_file, $e->getMessage());
}
}
return $reader;
}
public function isWorking() {
$filename = $this->maxmindGetFilename();
if (!is_readable($filename))
return false;
return true;
}
public function maxmindGetFilename() {
$data_filename = get_option('geoip-detect-manual_file_validated');
// Allow placing the file in the plugin folder for backwards compat
if (!$data_filename || !file_exists($data_filename)) {
$data_filename = GEOIP_PLUGIN_DIR . '/' . GEOIP_DETECT_DATA_FILENAME;
}
if (!file_exists($data_filename)) {
// Maybe site root changed?
$data_filename = $this->maxmindValidateFilename(get_option('geoip-detect-manual_file'));
}
$data_filename = apply_filters('geoip_detect_get_abs_db_filename', $data_filename);
return $data_filename;
}
public static function maxmindValidateFilename($filename) {
// Maybe make path absolute
if (file_exists(ABSPATH . $filename))
$filename = ABSPATH . $filename;
if (!is_readable($filename))
return '';
try {
$reader = new \GeoIp2\Database\Reader($filename);
$reader->metadata(); /* Try to read from it ... the result doesn't actually interest me. */
$reader->close();
} catch ( \Exception $e ) {
// Not readable, so do not accept this filename
return '';
}
return $filename;
}
protected function maxmindGetFileDescription() {
$reader = $this->getReader();
if (!method_exists($reader, 'metadata'))
return __('Maxmind File Database (file does not exist or is not readable)', 'geoip-detect');
try {
$metadata = $reader->metadata();
$desc = $metadata->description;
return $desc['en'];
} catch (\Exception $e) {
return __('Maxmind File Database (file does not exist or is not readable)', 'geoip-detect');
}
}
}
geoip_detect2_register_source(new ManualDataSource());
@@ -0,0 +1,169 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* maybe TODO:
* - warn email when counter is low ?
* - change to hostinfo or maxmind if credit is zero?
* - exclude spiders?
* - error logging
*/
namespace YellowTree\GeoipDetect\DataSources\Precision;
use YellowTree\GeoipDetect\DataSources\AbstractDataSource;
use YellowTree\GeoipDetect\DataSources\DataSourceRegistry;
class PrecisionReader extends \GeoIp2\WebService\Client implements \YellowTree\GeoipDetect\DataSources\ReaderInterface
{
public function __construct($userId, $licenseKey, $options) {
parent::__construct($userId, $licenseKey, array('en'), $options);
}
public function city($ip = 'me') {
$method = get_option('geoip-detect-precision_api_type', 'city');
$ret = null;
$callback = array($this, $method);
if (!is_callable($callback)) {
throw new \RuntimeException('Precision API: Unsupported method ' . $method);
}
if ($method == 'city')
$ret = parent::city($ip);
else
$ret = call_user_func_array($callback, array($ip));
/* Web-API-specific exceptions:
} catch (AuthenticationException $e) {
} catch (OutOfQueriesException $e) {
}
*/
if ($ret) {
$credits = $ret->maxmind->queriesRemaining; // This seems to be approximate.
update_option('geoip-detect-precision-remaining_credits', $credits);
}
return $ret;
}
public function close() { }
}
class PrecisionDataSource extends AbstractDataSource {
protected $known_api_types = array(
'country' => array('label' => 'Country'),
'city' => array('label' => 'City'),
'insights' => array('label' => 'Insights'));
public function __construct() {
parent::__construct();
}
public function getId() { return 'precision'; }
public function getLabel() { return __('Maxmind Precision Web-API', 'geoip-detect'); }
public function getDescriptionHTML() { return __('<a href="https://www.maxmind.com/en/geoip2-precision-services">Maxmind Precision Services</a>', 'geoip-detect'); }
public function getStatusInformationHTML() {
$html = '';
$html .= sprintf(__('API Type: %s', 'geoip-detect'), ucfirst(get_option('geoip-detect-precision_api_type', 'city'))) . '<br />';
$remaining = get_option('geoip-detect-precision-remaining_credits');
if ($remaining !== false) {
$html .= sprintf(__('Remaining Credits: ca. %s', 'geoip-detect'), $remaining) . '<br />';
}
if (!$this->isWorking())
$html .= '<div class="geoip_detect_error">' . __('Maxmind Precision only works with a given user id and secret.', 'geoip-detect') . '</div>';
return $html;
}
public function getParameterHTML() {
$user_id = (int) get_option('geoip-detect-precision-user_id');
$user_secret = esc_attr(get_option('geoip-detect-precision-user_secret'));
$current_api_type = get_option('geoip-detect-precision_api_type');
$label_user_id = __('User ID:', 'geoip-detect');
$label_user_secret = __('License key:', 'geoip-detect');
$label_api_type = __('API Type:', 'geoip-detect');
$html = <<<HTML
$label_user_id <input type="text" size="10" name="options_precision[user_id]" value="$user_id" /><br />
$label_user_secret <input type="text" autocomplete="off" size="20" name="options_precision[user_secret]" value="$user_secret" /><br />
$label_api_type <select name="options_precision[api_type]">
HTML;
foreach ($this->known_api_types as $name => $api_type) {
$html .= '<option ';
if ($name == $current_api_type)
$html .= 'selected="selected" ';
$html .= 'value="' . $name . '">' . $api_type['label'] . '</option>';
}
$html .= '</select>';
return $html;
}
public function saveParameters($post) {
$message = '';
if (isset($post['options_precision']['user_id'])) {
$user_id = (int) $post['options_precision']['user_id'];
update_option('geoip-detect-precision-user_id', $user_id);
}
if (isset($post['options_precision']['user_secret'])) {
$user_secret = trim($post['options_precision']['user_secret']);
update_option('geoip-detect-precision-user_secret', $user_secret);
}
if (isset($post['options_precision']['api_type'])) {
if (isset($this->known_api_types[$post['options_precision']['api_type']]))
update_option('geoip-detect-precision_api_type', $post['options_precision']['api_type']);
}
if (geoip_detect2_is_source_active('precision') && !$this->isWorking())
$message .= __('Maxmind Precision only works with a given user id and secret.', 'geoip-detect');
return $message;
}
public function getReader($locales = array('en'), $options = array()) {
if (!$this->isWorking())
return null;
$user_id = get_option('geoip-detect-precision-user_id');
$user_secret = get_option('geoip-detect-precision-user_secret');
$client = new PrecisionReader($user_id, $user_secret, $options);
return $client;
}
public function isWorking() {
$user_id = get_option('geoip-detect-precision-user_id');
$user_secret = get_option('geoip-detect-precision-user_secret');
return ! (empty($user_id) || empty($user_secret));
}
}
geoip_detect2_register_source(new PrecisionDataSource());
@@ -0,0 +1,141 @@
<?php
/*
Copyright 2013-2019 Yellow Tree, Siegen, Germany
Author: Benjamin Pick (wp-geoip-detect| |posteo.de)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
namespace YellowTree\GeoipDetect\DataSources;
class DataSourceRegistry {
private static $instance;
/* singleton */
private function __construct() {
$this->sources = array();
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new static();
}
return self::$instance;
}
protected $sources;
/**
* Register a Data source
* @param \YellowTree\GeoipDetect\DataSources\AbstractDataSource $source
*/
public function register($source) {
$id = $source->getId();
$this->sources[$id] = $source;
}
const DEFAULT_SOURCE = 'hostinfo';
public function getCurrentSourceId() {
return get_option('geoip-detect-source', self::DEFAULT_SOURCE);
}
/**
* Returns the currently chosen source.
* @deprecated Use getSource() instead
* @return \YellowTree\GeoipDetect\DataSources\AbstractDataSource
*/
public function getCurrentSource() {
return $this->getSource($this->getCurrentSourceId());
}
/**
* Returns the source known by this id.
* @param string $id Source id
* @return \YellowTree\GeoipDetect\DataSources\AbstractDataSource
*/
public function getSource($id) {
if (isset($this->sources[$id]))
return $this->sources[$id];
if (WP_DEBUG)
trigger_error('The source with id "' . $id . '" was requested, but no such source was found. Using default source instead.', E_USER_NOTICE);
if (isset($this->sources[self::DEFAULT_SOURCE]))
return $this->sources[self::DEFAULT_SOURCE];
return null;
}
/**
* Check if a source named $id exists.
* @param string $id
* @return boolean
*/
public function sourceExists($id) {
return isset($this->sources[$id]);
}
/**
* Choose a new source as "current source".
* @param string $id
*/
public function setCurrentSource($id) {
$oldSource = $this->getCurrentSource();
$newSource = $this->getSource($id);
if ($oldSource->getId() != $newSource->getId()) {
$oldSource->deactivate();
update_option('geoip-detect-source', $newSource->getId());
$newSource->activate();
}
update_option('geoip-detect-ui-has-chosen-source', true);
}
/**
* Returns all registered sources.
*
* @return array(\YellowTree\GeoipDetect\DataSources\AbstractDataSource)
*/
public function getAllSources() {
return $this->sources;
}
public function isSourceCachable($source) {
// Don't cache for file access based sources (not worth the effort/time)
$sources_not_cachable = apply_filters('geoip2_detect_sources_not_cachable', array('auto', 'manual', 'header'));
return !in_array($source, $sources_not_cachable);
}
public function isCachingUsed() {
return $this->isSourceCachable($this->getCurrentSourceId());
}
public function uninstall() {
foreach($this->sources as $source) {
$source->deactivate();
$source->uninstall();
}
// Delete all options from this plugin
foreach ( wp_load_alloptions() as $option => $value ) {
if ( strpos( $option, 'geoip-detect-' ) === 0 ) {
delete_option( $option );
}
}
}
}