Merged in feature/280-dev-dev01 (pull request #21)

auto-patch  280-dev-dev01-2024-01-19T16_41_58

* auto-patch  280-dev-dev01-2024-01-19T16_41_58
This commit is contained in:
Tony Volpe
2024-01-19 16:44:43 +00:00
parent 2699b5437a
commit be83910651
2125 changed files with 179300 additions and 35639 deletions

View File

@@ -0,0 +1,120 @@
<?php
/**
* IP Geo Block - Activate
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2013-2019 tokkonopapa
*/
// Stuff for resources
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-util.php';
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-opts.php';
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-logs.php';
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-cron.php';
require_once IP_GEO_BLOCK_PATH . 'admin/includes/class-admin-rewrite.php';
class IP_Geo_Block_Activate {
// Activate and deactivate main blog
private static function activate_main_blog( $settings ) {
IP_Geo_Block_Cron::start_update_db( $settings );
IP_Geo_Block_Opts::setup_validation_timing( $settings );
IP_Geo_Block_Admin_Rewrite::activate_rewrite_all( $settings['rewrite'] );
}
private static function deactivate_main_blog() {
IP_Geo_Block_Cron::stop_update_db();
IP_Geo_Block_Opts::setup_validation_timing();
IP_Geo_Block_Admin_Rewrite::deactivate_rewrite_all();
}
// Activate and deactivate each blog
public static function activate_blog() {
IP_Geo_Block_Opts::upgrade();
IP_Geo_Block_Logs::create_tables();
IP_Geo_Block_Logs::delete_cache_entry();
IP_Geo_Block_Cron::start_cache_gc();
}
private static function deactivate_blog() {
IP_Geo_Block_Cron::stop_cache_gc();
IP_Geo_Block_Logs::delete_cache_entry();
}
/**
* Register options into database table when the plugin is activated.
*
* @link https://wordpress.stackexchange.com/questions/181141/how-to-run-an-activation-function-when-plugin-is-network-activated-on-multisite
*/
public static function activate( $network_wide = FALSE ) {
// Update main blog first.
self::activate_blog();
// Get option of main blog.
$settings = IP_Geo_Block::get_option();
if ( is_multisite() && $network_wide ) {
global $wpdb;
$blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `$wpdb->blogs` ORDER BY `blog_id` ASC" );
// Skip the main blog.
array_shift( $blog_ids );
foreach ( $blog_ids as $id ) {
switch_to_blog( $id );
if ( $settings['network_wide'] ) {
// Copy settings of main site to individual site
$map = IP_Geo_Block::get_option( FALSE );
$settings['api_key']['GoogleMap'] = $map['api_key']['GoogleMap'];
IP_Geo_Block::update_option( $settings, FALSE );
}
// Initialize inidivisual site
self::activate_blog();
restore_current_blog();
}
}
if ( did_action( 'init' ) && current_user_can( 'manage_options' ) ) {
self::activate_main_blog( $settings );
}
}
/**
* Fired when the plugin is deactivated.
*
*/
public static function deactivate( $network_wide = FALSE ) {
add_action( 'shutdown', array( __CLASS__, 'deactivate_plugin' ) );
}
public static function deactivate_plugin() {
self::deactivate_blog();
if ( is_multisite() && is_main_site() ) {
global $wpdb;
$blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `$wpdb->blogs` ORDER BY `blog_id` ASC" );
// Skip the main blog.
array_shift( $blog_ids );
foreach ( $blog_ids as $id ) {
switch_to_blog( $id );
// Skip when this plugin is still active
if ( ! is_plugin_active( IP_GEO_BLOCK_BASE ) )
self::deactivate_blog();
restore_current_blog();
}
}
self::deactivate_main_blog();
}
}

View File

@@ -0,0 +1,678 @@
<?php
/**
* IP Geo Block - IP Address Geolocation API Class
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2013-2019 tokkonopapa
*/
/**
* Service type
*
*/
define( 'IP_GEO_BLOCK_API_TYPE_IPV4', 1 ); // can handle IPv4
define( 'IP_GEO_BLOCK_API_TYPE_IPV6', 2 ); // can handle IPv6
define( 'IP_GEO_BLOCK_API_TYPE_BOTH', 3 ); // can handle both IPv4 and IPv6
/**
* Abstract class
*
*/
abstract class IP_Geo_Block_API {
/**
* These values must be instantiated in child class
*
*//*
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_[IPV4 | IPV6 | BOTH],
'url' => 'http://example.com/%API_KEY%/%API_FORMAT%/%API_OPTION%/%API_IP%';
'api' => array(
'%API_IP%' => '', // should be set in build_url()
'%API_KEY%' => '', // should be set in __construct()
'%API_FORMAT%' => '', // may be set in child class
'%API_OPTION%' => '', // may be set in child class
),
'transform' => array(
'errorMessage' => '',
'countryCode' => '',
'countryName' => '',
'regionName' => '',
'cityName' => '',
'latitude' => '',
'longitude' => '',
)
);*/
/**
* Constructer & Destructer
*
*/
protected function __construct( $api_key = NULL ) {
if ( is_string( $api_key ) )
$this->template['api']['%API_KEY%'] = $api_key;
}
/**
* Build URL from template
*
*/
protected static function build_url( $ip, $template ) {
$template['api']['%API_IP%'] = $ip;
return str_replace(
array_keys( $template['api'] ),
array_values( $template['api'] ),
$template['url']
);
}
/**
* Fetch service provider to get geolocation information
*
*/
protected static function fetch_provider( $ip, $args, $template ) {
// check supported type of IP address
if ( ! ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && ( $template['type'] & IP_GEO_BLOCK_API_TYPE_IPV4 ) ) &&
! ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) && ( $template['type'] & IP_GEO_BLOCK_API_TYPE_IPV6 ) ) ) {
return FALSE;
}
// build query
$tmp = self::build_url( $ip, $template );
// https://codex.wordpress.org/Function_Reference/wp_remote_get
$res = @wp_remote_get( $tmp, $args ); // @since 2.7
if ( is_wp_error( $res ) )
return array( 'errorMessage' => $res->get_error_message() );
$tmp = wp_remote_retrieve_header( $res, 'content-type' );
$res = wp_remote_retrieve_body( $res );
// clear decoded data
$data = array();
// extract content type
// ex: "Content-type: text/plain; charset=utf-8"
if ( $tmp ) {
$tmp = explode( '/', $tmp, 2 );
$tmp = explode( ';', $tmp[1], 2 );
$tmp = trim( $tmp[0] );
}
switch ( $tmp ) {
// decode json
case 'json':
case 'html': // ipinfo.io, Xhanch
case 'plain': // geoPlugin
$data = json_decode( $res, TRUE ); // PHP 5 >= 5.2.0, PECL json >= 1.2.0
if ( NULL === $data ) // ipinfo.io (get_country)
$data[ $template['transform']['countryCode'] ] = trim( $res );
break;
// decode xml
case 'xml':
$tmp = '/\<(.+?)\>(?:\<\!\[CDATA\[)?([^\>]*?)(?:\]\]\>)?\<\/\\1\>/i';
if ( preg_match_all( $tmp, $res, $matches ) !== FALSE ) {
if ( is_array( $matches[1] ) && ! empty( $matches[1] ) ) {
foreach ( $matches[1] as $key => $val ) {
$data[ $val ] = $matches[2][ $key ];
}
}
}
break;
// unknown format
default:
return array( 'errorMessage' => "unsupported content type: $tmp" );
}
// transformation
$res = array();
foreach ( $template['transform'] as $key => $val ) {
if ( ! empty( $val ) && ! empty( $data[ $val ] ) )
$res[ $key ] = is_string( $data[ $val ] ) ? esc_html( $data[ $val ] ) : $data[ $val ];
}
// if country code is '-' or 'UNDEFINED' then error.
if ( isset( $res['countryCode'] ) && is_string( $res['countryCode'] ) )
$res['countryCode'] = preg_match( '/^[A-Z]{2}/', $res['countryCode'], $matches ) ? $matches[0] : NULL;
return $res;
}
/**
* Get geolocation information from service provider
*
*/
public function get_location( $ip, $args = array() ) {
return self::fetch_provider( $ip, $args, $this->template );
}
/**
* Get only country code
*
* Override this method if a provider supports this feature for quick response.
*/
public function get_country( $ip, $args = array() ) {
$res = $this->get_location( $ip, $args );
return FALSE === $res ? FALSE : ( empty( $res['countryCode'] ) ? NULL : $res['countryCode'] );
}
/**
* Convert provider name to class name
*
*/
public static function get_class_name( $provider ) {
$provider = 'IP_Geo_Block_API_' . preg_replace( '/[\W]/', '', $provider );
return class_exists( $provider, FALSE ) ? $provider : NULL;
}
/**
* Get option key
*
*/
public static function get_api_key( $provider, $options ) {
return empty( $options['providers'][ $provider ] ) ? NULL : $options['providers'][ $provider ];
}
/**
* Instance of inherited object
*
*/
private static $instance = array();
public static function get_instance( $provider, $options ) {
if ( $name = self::get_class_name( $provider ) ) {
if ( empty( self::$instance[ $name ] ) )
return self::$instance[ $name ] = new $name( self::get_api_key( $provider, $options ) );
else
return self::$instance[ $name ];
}
return NULL;
}
}
/**
* Class for IP-API.com
*
* URL : http://ip-api.com/
* Term of use : http://ip-api.com/docs/#usage_limits
* Licence fee : free for non-commercial use
* Rate limit : 240 requests per minute
* Sample URL : http://ip-api.com/json/2a00:1210:fffe:200::1
* Sample URL : http://ip-api.com/xml/yahoo.co.jp
* Input type : IP address (IPv4, IPv6 with limited coverage) / domain name
* Output type : json, xml
*/
class IP_Geo_Block_API_IPAPIcom extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'http://ip-api.com/%API_FORMAT%/%API_IP%',
'api' => array(
'%API_FORMAT%' => 'json',
),
'transform' => array(
'errorMessage' => 'error',
'countryCode' => 'countryCode',
'countryName' => 'country',
'regionName' => 'regionName',
'cityName' => 'city',
'latitude' => 'lat',
'longitude' => 'lon',
)
);
}
/**
* Class for GeoIPLookup.net
*
* URL : http://geoiplookup.net/
* Term of use : http://geoiplookup.net/terms-of-use.php
* Licence fee : free
* Rate limit : none
* Sample URL : http://api.geoiplookup.net/?query=2a00:1210:fffe:200::1
* Input type : IP address (IPv4, IPv6)
* Output type : xml
*/
class IP_Geo_Block_API_GeoIPLookup extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'http://api.geoiplookup.net/?query=%API_IP%',
'api' => array(),
'transform' => array(
'countryCode' => 'countrycode',
'countryName' => 'countryname',
'regionName' => 'countryname',
'cityName' => 'city',
'latitude' => 'latitude',
'longitude' => 'longitude',
)
);
}
/**
* Class for ipinfo.io
*
* URL : https://ipinfo.io/
* Term of use : https://ipinfo.io/developers#terms
* Licence fee : free
* Rate limit : 1,000 lookups daily
* Sample URL : https://ipinfo.io/124.83.187.140/json
* Sample URL : https://ipinfo.io/124.83.187.140/country
* Input type : IP address (IPv4)
* Output type : json
*/
class IP_Geo_Block_API_ipinfoio extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'https://ipinfo.io/%API_IP%/%API_FORMAT%%API_OPTION%',
'api' => array(
'%API_FORMAT%' => 'json',
'%API_OPTION%' => '',
),
'transform' => array(
'countryCode' => 'country',
'countryName' => 'country',
'regionName' => 'region',
'cityName' => 'city',
'latitude' => 'loc',
'longitude' => 'loc',
)
);
public function get_location( $ip, $args = array() ) {
$res = parent::get_location( $ip, $args );
if ( ! empty( $res ) && ! empty( $res['latitude'] ) ) {
$loc = explode( ',', $res['latitude'] );
$res['latitude' ] = $loc[0];
$res['longitude'] = $loc[1];
}
return $res;
}
public function get_country( $ip, $args = array() ) {
$this->template['api']['%API_FORMAT%'] = '';
$this->template['api']['%API_OPTION%'] = 'country';
return parent::get_country( $ip, $args );
}
}
/**
* Class for ipapi
*
* URL : https://ipapi.com/
* Term of use : https://ipapi.com/terms
* Licence fee : free to use the API
* Rate limit : 10,000 reqests per month
* Sample URL : http://api.ipapi.com/2a00:1210:fffe:200::1?access_key=...
* Input type : IP address (IPv4, IPv6)
* Output type : json
*/
class IP_Geo_Block_API_ipapi extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'http://api.ipapi.com/%API_IP%?access_key=%API_KEY%',
'api' => array(),
'transform' => array(
'countryCode' => 'country_code',
'countryName' => 'country_name',
'cityName' => 'city',
'latitude' => 'latitude',
'longitude' => 'longitude',
'error' => 'error',
)
);
public function get_location( $ip, $args = array() ) {
$res = parent::get_location( $ip, $args );
if ( isset( $res['countryName'] ) ) {
$res['countryCode'] = esc_html( $res['countryCode'] );
$res['countryName'] = esc_html( $res['countryName'] );
$res['latitude' ] = esc_html( $res['latitude' ] );
$res['longitude' ] = esc_html( $res['longitude' ] );
return $res;
} else {
return array( 'errorMessage' => esc_html( $res['error']['info'] ) );
}
}
}
/**
* Class for Ipdata.co
*
* URL : https://ipdata.co/
* Term of use : https://ipdata.co/terms.html
* Licence fee : free
* Rate limit : 1,500 lookups free daily
* Sample URL : https://api.ipdata.co/8.8.8.8?api-key=...
* Input type : IP address (IPv4, IPv6)
* Output type : json
*/
class IP_Geo_Block_API_Ipdataco extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'https://api.ipdata.co/%API_IP%?api-key=%API_KEY%',
'api' => array(
'%API_FORMAT%' => 'json',
),
'transform' => array(
'countryCode' => 'country_code',
'countryName' => 'country_name',
'regionName' => 'region',
'cityName' => 'city',
'latitude' => 'latitude',
'longitude' => 'longitude',
)
);
}
/**
* Class for ipstack
*
* URL : https://ipstack.com/
* Term of use : https://ipstack.com/terms
* Licence fee : free for registered user
* Rate limit : 10,000 queries per month for free (https can be available for premium users)
* Sample URL : http://api.ipstack.com/186.116.207.169?access_key=YOUR_ACCESS_KEY&output=json&legacy=1
* Input type : IP address (IPv4, IPv6) / domain name
* Output type : json, xml
*/
class IP_Geo_Block_API_ipstack extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'http://api.ipstack.com/%API_IP%?access_key=%API_KEY%&output=%API_FORMAT%',
'api' => array(
'%API_FORMAT%' => 'json',
),
'transform' => array(
'countryCode' => 'country_code',
'countryName' => 'country_name',
'regionName' => 'region_name',
'cityName' => 'city',
'latitude' => 'latitude',
'longitude' => 'longitude',
)
);
}
/**
* Class for IPInfoDB
*
* URL : https://ipinfodb.com/
* Term of use :
* Licence fee : free (need to regist to get API key)
* Rate limit : 2 queries/second for registered user
* Sample URL : https://api.ipinfodb.com/v3/ip-city/?key=...&format=xml&ip=124.83.187.140
* Sample URL : https://api.ipinfodb.com/v3/ip-country/?key=...&format=xml&ip=yahoo.co.jp
* Input type : IP address (IPv4, IPv6) / domain name
* Output type : json, xml
*/
class IP_Geo_Block_API_IPInfoDB extends IP_Geo_Block_API {
protected $template = array(
'type' => IP_GEO_BLOCK_API_TYPE_BOTH,
'url' => 'https://api.ipinfodb.com/v3/%API_OPTION%/?key=%API_KEY%&format=%API_FORMAT%&ip=%API_IP%',
'api' => array(
'%API_FORMAT%' => 'xml',
'%API_OPTION%' => 'ip-city',
),
'transform' => array(
'countryCode' => 'countryCode',
'countryName' => 'countryName',
'regionName' => 'regionName',
'cityName' => 'cityName',
'latitude' => 'latitude',
'longitude' => 'longitude',
)
);
public function __construct( $api_key = NULL ) {
// sanitization
parent::__construct( preg_replace( '/\W/', '', $api_key ) );
}
public function get_country( $ip, $args = array() ) {
$this->api_template['%API_OPTION%'] = 'ip-country';
return parent::get_country( $ip, $args );
}
}
/**
* Class for Cache
*
* Input type : IP address (IPv4, IPv6)
* Output type : array
*/
class IP_Geo_Block_API_Cache extends IP_Geo_Block_API {
// memory cache
protected static $memcache = array();
public static function update_cache( $hook, $validate, $settings, $countup = TRUE ) {
$time = $_SERVER['REQUEST_TIME'];
$cache = self::get_cache( $ip = $validate['ip'], $settings['cache_hold'] );
if ( $cache ) {
$fail = isset( $validate['fail'] ) ? $validate['fail'] : 0;
$call = $cache['reqs'] + ( $countup ? 1 : 0 ); // prevent duplicate count up
$last = $cache['last'];
$view = $cache['view'];
} else { // if new cache then reset these values
$fail = 0;
$call = 1;
$last = $time;
$view = 1;
}
if ( $cache && 'public' === $hook ) {
if ( $time - $last > $settings['behavior']['time'] )
$view = 1;
else
++$view;
$last = $time;
}
$cache = array(
'time' => $time,
'ip' => $ip,
'hook' => $hook,
'asn' => $validate['asn' ], // @since 3.0.4
'code' => $validate['code'],
'auth' => $validate['auth'], // get_current_user_id() > 0
'fail' => $fail, // $validate['auth'] ? 0 : $fail,
'reqs' => $settings['save_statistics'] ? $call : 0,
'last' => $last,
'view' => $view,
'host' => isset( $validate['host'] ) && $validate['host'] !== $ip ? $validate['host'] : '',
);
// do not update cache while installing geolocation databases
if ( $settings['cache_hold'] && ! ( $validate['auth'] && 'ZZ' === $validate['code'] ) )
IP_Geo_Block_Logs::update_cache( $cache );
return self::$memcache[ $ip ] = $cache;
}
public static function clear_cache() {
IP_Geo_Block_Logs::clear_cache();
self::$memcache = array();
}
public static function get_cache( $ip, $use_cache = TRUE ) {
if ( isset( self::$memcache[ $ip ] ) )
return self::$memcache[ $ip ];
else
return $use_cache ? self::$memcache[ $ip ] = IP_Geo_Block_Logs::search_cache( $ip ) : NULL;
}
public function get_location( $ip, $args = array() ) {
if ( $cache = self::get_cache( $ip ) )
return array( 'countryCode' => $cache['code'] );
else
return array( 'errorMessage' => 'not in the cache' );
}
public function get_country( $ip, $args = array() ) {
return ( $cache = self::get_cache( $ip ) ) ? ( isset( $args['cache'] ) ? $cache : $cache['code'] ) : NULL;
}
}
/**
* Provider support class
*
*/
class IP_Geo_Block_Provider {
protected static $providers = array(
'IP-API.com' => array(
'key' => FALSE,
'type' => 'IPv4, IPv6 / free for non-commercial use',
'link' => '<a rel="noreferrer" href="http://ip-api.com/" title="IP-API.com - Free Geolocation API">http://ip-api.com/</a>&nbsp;(IPv4, IPv6 / free for non-commercial use)',
),
'GeoIPLookup' => array(
'key' => NULL,
'type' => 'IPv4, IPv6 / free',
'link' => '<a rel="noreferrer" href="http://geoiplookup.net/" title="What Is My IP Address | GeoIP Lookup">GeoIPLookup.net</a>&nbsp;(IPv4, IPv6 / free)',
),
'ipinfo.io' => array(
'key' => NULL,
'type' => 'IPv4, IPv6 / free',
'link' => '<a rel="noreferrer" href="https://ipinfo.io/" title="IP Address API and Data Solutions">https://ipinfo.io/</a>&nbsp;(IPv4, IPv6 / free up to 1,000 lookups daily)',
),
'ipapi' => array(
'key' => '',
'type' => 'IPv4, IPv6 / free',
'link' => '<a rel="noreferrer" href="https://ipapi.com/" title="ipapi - IP Address Lookup and Geolocation API">https://ipapi.com/</a>&nbsp;(IPv4, IPv6 / free up to 10,000 lookups monthly for registered user)',
),
'Ipdata.co' => array(
'key' => '',
'type' => 'IPv4, IPv6 / free',
'link' => '<a rel="noreferrer" href="https://ipdata.co/" title="ipdata.co - IP Geolocation and Threat Data API">https://ipdata.co/</a>&nbsp;(IPv4, IPv6 / free up to 1,500 lookups daily for registered user)',
),
'ipstack' => array(
'key' => '',
'type' => 'IPv4, IPv6 / free for registered user',
'link' => '<a rel="noreferrer" href="https://ipstack.com/" title="ipstack - Free IP Geolocation API">https://ipstack.com/</a>&nbsp;(IPv4, IPv6 / free for registered user)',
),
'IPInfoDB' => array(
'key' => '',
'type' => 'IPv4, IPv6 / free for registered user',
'link' => '<a rel="noreferrer" href="https://ipinfodb.com/" title="Free IP Geolocation Tools and API| IPInfoDB">https://ipinfodb.com/</a>&nbsp;(IPv4, IPv6 / free for registered user)',
),
);
// Internal DB
protected static $internals = array(
'Cache' => array(
'key' => NULL,
'type' => 'IPv4, IPv6',
'link' => NULL,
),
);
/**
* Register and get addon provider class information
*
*/
public static function register_addon( $api ) {
self::$internals += $api;
}
public static function get_addons( $providers = array(), $force = FALSE ) {
$apis = array();
foreach ( self::$internals as $key => $val ) {
if ( 'Cache' !== $key && ( $force || ! isset( $providers[ $key ] ) || ! empty( $providers[ $key ] ) ) )
$apis[] = $key;
}
return $apis;
}
/**
* Returns the pairs of provider name and API key
*
*/
public static function get_providers( $key = 'key', $rand = FALSE, $cache = FALSE, $all = TRUE ) {
// add internal DB
$list = array();
foreach ( self::$internals as $provider => $tmp ) {
if ( 'Cache' !== $provider || $cache )
$list[ $provider ] = $tmp[ $key ];
}
if ( $all ) {
$tmp = array_keys( self::$providers );
// randomize
if ( $rand )
shuffle( $tmp );
foreach ( $tmp as $name ) {
$list[ $name ] = self::$providers[ $name ][ $key ];
}
}
return $list;
}
/**
* Returns providers name list which are checked in settings
*
*/
public static function get_valid_providers( $settings, $rand = TRUE, $cache = TRUE, $all = FALSE ) {
$list = array();
$providers = $settings['providers' ]; // list of not selected and selected with api key
$cache &= $settings['cache_hold']; // exclude `Cache` when `IP address cache` is disabled
foreach ( self::get_providers( 'key', $rand, $cache, empty( $settings['restrict_api'] ) || $all ) as $name => $key ) {
// ( if $name has api key ) || ( if $name that does not need api key is selected )
if ( ! empty( $providers[ $name ] ) || ( ! isset( $providers[ $name ] ) && NULL === $key ) ) {
$list[] = $name;
}
}
return $list;
}
}
/**
* Load additional plugins
*
*/
if ( class_exists( 'IP_Geo_Block', FALSE ) ) {
// Avoid "The plugin does not have a valid header" on activation under WP4.0
if ( is_plugin_active( IP_GEO_BLOCK_BASE ) ) {
// Get absolute path to the geo-location API
$dir = IP_Geo_Block::get_option();
if ( $dir['api_dir'] ) {
$dir = IP_Geo_Block_Util::slashit(
apply_filters( IP_Geo_Block::PLUGIN_NAME . '-api-dir', $dir['api_dir'] )
);
// Scan API directory
$plugins = ( is_dir( $dir ) ? scandir( $dir, defined( 'SCANDIR_SORT_DESCENDING' ) ? SCANDIR_SORT_DESCENDING : 1 ) : FALSE );
// Load addons by heigher priority order
if ( FALSE !== $plugins ) {
$exclude = array( '.', '..' );
foreach ( $plugins as $plugin ) {
if ( ! in_array( $plugin, $exclude, TRUE ) && is_dir( $dir.$plugin ) ) {
@include $dir.$plugin.'/class-'.$plugin.'.php';
}
}
}
}
}
}

View File

@@ -0,0 +1,440 @@
<?php
/**
* IP Geo Block - Cron Class
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2013-2019 tokkonopapa
*/
class IP_Geo_Block_Cron {
/**
* Cron scheduler.
*
*/
private static function schedule_cron_job( &$update, $db, $immediate = FALSE ) {
wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( $immediate ) );
if ( $update['auto'] || $immediate ) {
$now = time();
$next = $now + ( $immediate ? 0 : DAY_IN_SECONDS );
if ( FALSE === $immediate ) {
++$update['retry'];
$cycle = DAY_IN_SECONDS * (int)$update['cycle'];
if ( isset( $db['ipv4_last'] ) ) {
// in case of Maxmind Legacy or IP2Location
if ( $now - (int)$db['ipv4_last'] < $cycle &&
$now - (int)$db['ipv6_last'] < $cycle ) {
$update['retry'] = 0;
$next = max( (int)$db['ipv4_last'], (int)$db['ipv6_last'] ) +
$cycle + rand( DAY_IN_SECONDS, DAY_IN_SECONDS * 6 );
}
} else {
// in case of Maxmind GeoLite2
if ( $now - (int)$db['ip_last'] < $cycle ) {
$update['retry'] = 0;
$next = (int)$db['ip_last'] +
$cycle + rand( DAY_IN_SECONDS, DAY_IN_SECONDS * 6 );
}
}
}
wp_schedule_single_event( $next, IP_Geo_Block::CRON_NAME, array( $immediate ) );
}
}
/**
* Database auto downloader.
*
* This function is called when:
* 1. Plugin is activated
* 2. WP Cron is kicked
* under the following condition:
* A. Once per site when this plugin is activated on network wide
* B. Multiple time for each blog when this plugin is individually activated
*/
public static function exec_update_db( $immediate = FALSE ) {
$settings = IP_Geo_Block::get_option();
// extract ip address from transient API to confirm the request source
if ( $immediate ) {
set_transient( IP_Geo_Block::CRON_NAME, IP_Geo_Block::get_ip_address( $settings ), MINUTE_IN_SECONDS );
add_filter( IP_Geo_Block::PLUGIN_NAME . '-ip-addr', array( __CLASS__, 'extract_ip' ) );
}
$context = IP_Geo_Block::get_instance();
$args = IP_Geo_Block::get_request_headers( $settings );
// download database files (higher priority order)
foreach ( $providers = IP_Geo_Block_Provider::get_addons( $settings['providers'] ) as $provider ) {
if ( $geo = IP_Geo_Block_API::get_instance( $provider, $settings ) ) {
$res[ $provider ] = $geo->download( $settings[ $provider ], $args );
// re-schedule cron job
self::schedule_cron_job( $settings['update'], $settings[ $provider ], FALSE );
// update provider settings
self::update_settings( $settings, array( 'update', $provider ) );
// skip to update settings in case of InfiniteWP that could be in a different country
if ( isset( $_SERVER['HTTP_X_REQUESTED_FROM'] ) && FALSE !== strpos( $_SERVER['HTTP_X_REQUESTED_FROM'], 'InfiniteWP' ) )
continue;
// update matching rule immediately
if ( $immediate && 'done' !== get_transient( IP_Geo_Block::CRON_NAME ) ) {
$validate = $context->validate_ip( 'admin', $settings );
if ( 'ZZ' === $validate['code'] )
continue;
// matching rule should be reset when blocking happens
if ( 'passed' !== $validate['result'] )
$settings['matching_rule'] = -1;
// setup country code in whitelist if it needs to be initialized
if ( -1 === (int)$settings['matching_rule'] ) {
$settings['matching_rule'] = 0; // white list
// when the country code doesn't exist in whitelist, then add it
if ( FALSE === strpos( $settings['white_list'], $validate['code'] ) )
$settings['white_list'] .= ( $settings['white_list'] ? ',' : '' ) . $validate['code'];
}
// update option settings
self::update_settings( $settings, array( 'matching_rule', 'white_list' ) );
// finished to update matching rule
set_transient( IP_Geo_Block::CRON_NAME, 'done', 5 * MINUTE_IN_SECONDS );
// trigger update action
do_action( IP_Geo_Block::PLUGIN_NAME . '-db-updated', $settings, $validate['code'] );
}
}
}
return isset( $res ) ? $res : NULL;
}
/**
* Update setting data according to the site type.
*
*/
private static function update_settings( $src, $keys = array() ) {
// for multisite
if ( is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) ) {
global $wpdb;
$blog_ids = $wpdb->get_col( "SELECT `blog_id` FROM `$wpdb->blogs`" );
foreach ( $blog_ids as $id ) {
switch_to_blog( $id );
$dst = IP_Geo_Block::get_option( FALSE );
foreach ( $keys as $key ) {
$dst[ $key ] = $src[ $key ];
}
IP_Geo_Block::update_option( $dst, FALSE );
restore_current_blog();
}
}
// for single site
else {
IP_Geo_Block::update_option( $src );
}
}
/**
* Extract ip address from transient API.
*
*/
public static function extract_ip( $ip ) {
return filter_var(
$ip_self = get_transient( IP_Geo_Block::CRON_NAME ), FILTER_VALIDATE_IP
) ? $ip_self : $ip;
}
/**
* Kick off a cron job to download database immediately in background on activation.
*
*/
public static function start_update_db( $settings, $immediate = TRUE ) {
// updating should be done by main site when this plugin is activated for network
if ( is_main_site() || ! is_plugin_active_for_network( IP_GEO_BLOCK_BASE ) )
self::schedule_cron_job( $settings['update'], NULL, $immediate );
}
public static function stop_update_db() {
wp_clear_scheduled_hook( IP_Geo_Block::CRON_NAME, array( FALSE ) ); // @since 2.1.0
// wait until updating has finished to avoid race condition with IP_Geo_Block_Opts::install_api()
$time = 0;
while ( ( $stat = get_transient( IP_Geo_Block::CRON_NAME ) ) && 'done' !== $stat ) {
sleep( 1 );
if ( ++$time > 5 * MINUTE_IN_SECONDS ) {
break;
}
}
}
/**
* Kick off a cron job to garbage collection for IP address cache.
*
*/
public static function exec_cache_gc( $settings ) {
self::stop_cache_gc();
IP_Geo_Block_Logs::delete_expired( array(
min( 365, max( 1, (int)$settings['validation']['explogs'] ) ) * DAY_IN_SECONDS,
(int)$settings['cache_time']
) );
self::start_cache_gc( $settings );
}
public static function start_cache_gc( $settings = FALSE ) {
if ( ! wp_next_scheduled( IP_Geo_Block::CACHE_NAME ) ) {
$settings or $settings = IP_Geo_Block::get_option();
wp_schedule_single_event( time() + max( $settings['cache_time_gc'], MINUTE_IN_SECONDS ), IP_Geo_Block::CACHE_NAME );
}
}
public static function stop_cache_gc() {
wp_clear_scheduled_hook( IP_Geo_Block::CACHE_NAME ); // @since 2.1.0
}
/**
* Decompresses gz archive and output to the file.
*
* @param string $src full path to the downloaded file.
* @param string $dst full path to extracted file.
* @return TRUE or array of error code and message.
*/
private static function gzfile( $src, $dst ) {
try {
if ( FALSE === ( $gz = gzopen( $src, 'r' ) ) )
throw new Exception(
sprintf( __( 'Unable to read <code>%s</code>. Please check the permission.', 'ip-geo-block' ), $src )
);
if ( FALSE === ( $fp = @fopen( $dst, 'cb' ) ) )
throw new Exception(
sprintf( __( 'Unable to write <code>%s</code>. Please check the permission.', 'ip-geo-block' ), $filename )
);
if ( ! flock( $fp, LOCK_EX ) )
throw new Exception(
sprintf( __( 'Can\'t lock <code>%s</code>. Please try again after a while.', 'ip-geo-block' ), $filename )
);
ftruncate( $fp, 0 ); // truncate file
// same block size in wp-includes/class-http.php
while ( $data = gzread( $gz, 4096 ) ) {
fwrite( $fp, $data, strlen( $data ) );
}
}
catch ( Exception $e ) {
$err = array(
'code' => $e->getCode(),
'message' => $e->getMessage(),
);
}
if ( ! empty( $fp ) ) {
fflush( $fp ); // flush output before releasing the lock
flock ( $fp, LOCK_UN ); // release the lock
fclose( $fp );
}
return empty( $err ) ? TRUE : $err;
}
/**
* Download zip/gz file, uncompress and save it to specified file
*
* @param string $url URL of remote file to be downloaded.
* @param array $args request headers.
* @param string $filename full path to the downloaded file.
* @param int $modified time of last modified on the remote server.
* @return array status message.
*/
public static function download_zip( $url, $args, $files, $modified ) {
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
// get extension
$ext = strtolower( pathinfo( $url, PATHINFO_EXTENSION ) );
if ( 'tar' === strtolower( pathinfo( pathinfo( $url, PATHINFO_FILENAME ), PATHINFO_EXTENSION ) ) )
$ext = 'tar';
// check file (1st parameter includes absolute path in case of array)
$filename = is_array( $files ) ? $files[0] : (string)$files;
if ( ! $fs->exists( $filename ) )
$modified = 0;
// set 'If-Modified-Since' request header
$args += array(
'headers' => array(
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Encoding' => 'gzip, deflate',
'If-Modified-Since' => gmdate( DATE_RFC1123, (int)$modified ),
),
);
// fetch file and get response code & message
if ( isset( $args['method'] ) && 'GET' === $args['method'] )
$src = wp_remote_get ( ( $url = esc_url_raw( $url ) ), $args );
else
$src = wp_remote_head( ( $url = esc_url_raw( $url ) ), $args );
if ( is_wp_error( $src ) )
return array(
'code' => $src->get_error_code(),
'message' => $src->get_error_message(),
);
$code = wp_remote_retrieve_response_code ( $src );
$mesg = wp_remote_retrieve_response_message( $src );
$data = wp_remote_retrieve_header( $src, 'last-modified' );
$modified = $data ? strtotime( $data ) : $modified;
if ( 304 == $code )
return array(
'code' => $code,
'message' => __( 'Your database file is up-to-date.', 'ip-geo-block' ),
'filename' => $filename,
'modified' => $modified,
);
elseif ( 200 != $code )
return array(
'code' => $code,
'message' => $code.' '.$mesg,
);
try {
// in case that the server which does not support HEAD method
if ( isset( $args['method'] ) && 'GET' === $args['method'] ) {
$data = wp_remote_retrieve_body( $src );
if ( 'gz' === $ext ) {
if ( function_exists( 'gzdecode') ) { // @since PHP 5.4.0
if ( FALSE === $fs->put_contents( $filename, gzdecode( $data ) ) )
throw new Exception(
sprintf( __( 'Unable to write <code>%s</code>. Please check the permission.', 'ip-geo-block' ), $filename )
);
}
else {
$src = get_temp_dir() . basename( $url ); // $src should be removed
$fs->put_contents( $src, $data );
if ( TRUE !== ( $ret = self::gzfile( $src, $filename ) ) ) {
$err = $ret;
}
}
}
elseif ( 'tar' === $ext && class_exists( 'PharData', FALSE ) ) { // @since PECL phar 2.0.0
$name = wp_remote_retrieve_header( $src, 'content-disposition' );
$name = explode( 'filename=', $name );
$name = array_pop( $name ); // e.g. GeoLite2-Country_20180102.tar.gz
$src = ( $tmp = get_temp_dir() ) . $name; // $src should be removed
// CVE-2015-6833: A directory traversal when extracting ZIP files could be used to overwrite files
// outside of intended area via a `..` in a ZIP archive entry that is mishandled by extractTo().
if ( $fs->put_contents( $src, $data ) ) {
$data = new PharData( $src, FilesystemIterator::SKIP_DOTS ); // get archives
// make the list of contents to be extracted from archives.
// when the list doesn't match the contents in archives, extractTo() may be crushed on windows.
$dst = $data->getSubPathname(); // e.g. GeoLite2-Country_20180102
foreach ( $files as $key => $val ) {
$files[ $key ] = $dst.'/'.basename( $val );
}
// extract specific files from archives into temporary directory and copy it to the destination.
$data->extractTo( $tmp .= $dst, $files /* NULL */, TRUE ); // $tmp should be removed
// copy extracted files to Geolocation APIs directory
$dst = dirname( $filename );
foreach ( $files as $val ) {
// should the destination be exclusive with LOCK_EX ?
// $fs->put_contents( $dst.'/'.basename( $val ), $fs->get_contents( $tmp.'/'.$val ) );
$fs->copy( $tmp.'/'.$val, $dst.'/'.basename( $val ), TRUE );
}
}
}
}
// downloaded and unzip
else {
// download file
$src = download_url( $url );
if ( is_wp_error( $src ) )
throw new Exception(
$src->get_error_code() . ' ' . $src->get_error_message()
);
// unzip file
if ( 'gz' === $ext ) {
if ( TRUE !== ( $ret = self::gzfile( $src, $filename ) ) ) {
$err = $ret;
}
}
elseif ( 'zip' === $ext && class_exists( 'ZipArchive', FALSE ) ) {
$tmp = get_temp_dir(); // @since 2.5
$ret = $fs->unzip_file( $src, $tmp ); // @since 2.5
if ( is_wp_error( $ret ) )
throw new Exception(
$ret->get_error_code() . ' ' . $ret->get_error_message()
);
if ( FALSE === ( $data = $fs->get_contents( $tmp .= basename( $filename ) ) ) )
throw new Exception(
sprintf( __( 'Unable to read <code>%s</code>. Please check the permission.', 'ip-geo-block' ), $tmp )
);
if ( FALSE === $fs->put_contents( $filename, $data ) )
throw new Exception(
sprintf( __( 'Unable to write <code>%s</code>. Please check the permission.', 'ip-geo-block' ), $filename )
);
}
else {
throw new Exception( __( 'gz or zip is not supported on your system.', 'ip-geo-block' ) );
}
}
}
// error handler
catch ( Exception $e ) {
$err = array(
'code' => $e->getCode(),
'message' => $e->getMessage(),
);
}
! empty ( $gz ) and gzclose( $gz );
! empty ( $tmp ) and $fs->delete( $tmp, TRUE ); // should be removed recursively in case of directory
is_string( $src ) && $fs->is_file( $src ) and $fs->delete( $src );
return empty( $err ) ? array(
'code' => $code,
'message' => sprintf( __( 'Last update: %s', 'ip-geo-block' ), IP_Geo_Block_Util::localdate( $modified ) ),
'filename' => $filename,
'modified' => $modified,
) : $err;
}
}

View File

@@ -0,0 +1,330 @@
<?php
/**
* IP Geo Block - Filesystem
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @link https://codex.wordpress.org/Filesystem_API
* @copyright 2013-2019 tokkonopapa
*/
class IP_Geo_Block_FS {
/**
* Private variables of this class.
*
*/
private static $instance = NULL;
private static $method = 'direct';
/**
* Create an instance of this class.
*
*/
private static function get_instance() {
return self::$instance ? self::$instance : ( self::$instance = new self );
}
/**
* Initialize and return instance of this class.
*
*/
public static function init( $msg = NULL ) {
require_once ABSPATH . 'wp-admin/includes/template.php'; // for submit_button() in request_filesystem_credentials()
require_once ABSPATH . 'wp-admin/includes/file.php'; // for get_filesystem_method(), request_filesystem_credentials()
global $wp_filesystem;
// check already assigned by WP_Filesystem()
if ( empty( $wp_filesystem ) ) {
if (0) {
// https://codex.wordpress.org/Filesystem_API#Tips_and_Tricks
if ( 'direct' === ( self::$method = get_filesystem_method() ) ) { // @since 2.5.0
// request_filesystem_credentials() can be run without any issues and don't need to worry about passing in a URL
$creds = request_filesystem_credentials( admin_url(), '', FALSE, FALSE, NULL ); // @since 2.5.0
// initialize the API @since 2.5.0
WP_Filesystem( $creds );
}
elseif ( class_exists( 'IP_Geo_Block_Admin', FALSE ) ) {
IP_Geo_Block_Admin::add_admin_notice(
'error',
sprintf( __( 'This plugin does not support method &#8220;%s&#8221; for FTP or SSH based file operations. Please refer to <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants" title="Editing wp-config.php &laquo; WordPress Codex">this document</a> for more details.', 'ip-geo-block' ), self::$method )
);
}
} else {
// Determines the method on the filesystem.
self::$method = get_filesystem_method();
if ( FALSE !== ( $creds = request_filesystem_credentials( admin_url(), '', FALSE, FALSE, NULL ) ) ) {
WP_Filesystem( $creds );
}
elseif ( class_exists( 'IP_Geo_Block_Admin', FALSE ) ) {
IP_Geo_Block_Admin::add_admin_notice(
'error',
__( 'You should define some constants in your <code>wp-config.php</code> for FTP or SSH based file operations. Please refer to <a href="https://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants" title="Editing wp-config.php &laquo; WordPress Codex">this document</a> for more details.', 'ip-geo-block' )
);
}
}
}
return self::get_instance();
}
// Add slash at the end of string.
private function slashit( $string ) {
return rtrim( $string, '/\\' ) . '/';
}
// Get absolute path.
private function absolute_path( $file ) {
global $wp_filesystem;
$path = str_replace( ABSPATH, $wp_filesystem->abspath(), dirname( $file ) );
return $this->slashit( $path ) . basename( $file );
}
/**
* Get method of the file system;
*
* @return string method of file system
*/
public function get_method() {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return self::$method;
}
/**
* Check if a file or directory exists.
*
* @param string $file Path to file/directory.
* @return bool Whether $file exists or not.
*/
public function exists( $file ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->exists( $this->absolute_path( $file ) );
}
/**
* Validate if path is file
*
* @param string $path
* @return bool
*/
public function is_file( $path ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->is_file( $this->absolute_path( $path ) );
}
/**
* Validate if path is directory
*
* @param string $path
* @return bool
*/
public function is_dir( $path ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->is_dir( $this->absolute_path( $path ) );
}
/**
* Check if a file is readable.
*
* @param string $file Path to file.
* @return bool Whether $file is readable.
*/
public function is_readable( $file ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->is_readable( $this->absolute_path( $file ) );
}
/**
* Check if a file or directory is writable.
*
* @param string $file Path to file.
* @return bool Whether $file is writable.
*/
public function is_writable( $file ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->is_writable( $this->absolute_path( $file ) );
}
/**
* Make a directory
*
* @param string $path
* @param mixed $chmod
* @param mixed $chown
* @param mixed $chgrp
* @return bool
*/
public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->mkdir( $this->absolute_path( $path ), $chmod, $chown, $chgrp );
}
/**
* Delete a file or directory.
*
* @param string $file Path to the file.
* @param bool $recursive If set True changes file group recursively.
* @param bool $type Type of resource. 'f' for file, 'd' for directory.
* @return bool True if the file or directory was deleted, false on failure.
*/
public function delete( $file, $recursive = FALSE, $type = FALSE ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->delete( $this->absolute_path( $file ), $recursive, $type );
}
/**
* Copy a file.
*
* @param string $src
* @param string $dst
* @param bool $overwrite
* @param int $mode
* @return bool
*/
public function copy( $src, $dst, $overwrite = FALSE, $mode = FALSE ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->copy(
$this->absolute_path( $src ),
$this->absolute_path( $dst ),
$overwrite, $mode
);
}
/**
* Write a string to a file with an exclusive lock.
*
* @param string $file Remote path to the file where to write the data.
* @param string $contents The data to write.
* @param int $mode The file permissions as octal number, usually 0644. Default false.
* @return bool
*/
public function put_contents( $file, $contents, $mode = FALSE ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
if ( 'direct' === self::$method )
return @file_put_contents( $this->absolute_path( $file ), $contents, LOCK_EX );
else
return $wp_filesystem->put_contents( $this->absolute_path( $file ), $contents, $mode );
}
/**
* Reads entire file into a string
*
* @access public
*
* @param string $file Name of the file to read.
* @return string|bool The data of contents or false on failure.
*/
public function get_contents( $file ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
if ( 'direct' === self::$method )
return @file_get_contents( $this->absolute_path( $file ) );
else
return $wp_filesystem->get_contents( $this->absolute_path( $file ) );
}
/**
* Read entire file into an array.
*
* @param string $file Filename.
* @return array|bool An array of contents or false on failure.
*/
public function get_contents_array( $file ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return array();
// https://php.net/manual/en/function.file.php#refsect1-function.file-returnvalues
@ini_set( 'auto_detect_line_endings', TRUE );
if ( ! $this->is_file( $file ) || ! $this->is_readable( $file ) )
return FALSE;
if ( 'direct' === self::$method )
return file( $this->absolute_path( $file ), FILE_IGNORE_NEW_LINES );
$file = $wp_filesystem->get_contents_array( $this->absolute_path( $file ) );
return FALSE !== $file ? array_map( 'rtrim', $file ) : FALSE;
}
/**
* Unzips a specified ZIP file to a location on the Filesystem via the WordPress Filesystem Abstraction.
*
* @param string $src Full path and filename of zip archive.
* @param string $dst Full path on the filesystem to extract archive to.
* @return WP_Error on failure, True on success
*/
public function unzip_file( $src, $dst ) {
return unzip_file( $src, $this->absolute_path( $dst ) );
}
/**
* Get details for files in a directory or a specific file.
*
* @since 2.5.0
*
* @param string $path
* @param bool $include_hidden
* @param bool $recursive
* @return array|bool {
* Array of files. False if unable to list directory contents.
* @type string 'name' Name of the file/directory.
* @type string 'perms' *nix representation of permissions.
* @type int 'permsn' Octal representation of permissions.
* @type string 'owner' Owner name or ID.
* @type int 'size' Size of file in bytes.
* @type int 'lastmodunix' Last modified unix timestamp.
* @type mixed 'lastmod' Last modified month (3 letter) and day (without leading 0).
* @type int 'time' Last modified time.
* @type string 'type' Type of resource. 'f' for file, 'd' for directory.
* @type mixed 'files' If a directory and $recursive is true, contains another array of files.
* }
*/
public function dirlist( $path, $include_hidden = FALSE, $recursive = FALSE ) {
global $wp_filesystem;
if ( empty( $wp_filesystem ) )
return FALSE;
return $wp_filesystem->dirlist( $path, $include_hidden, $recursive );
}
}

View File

@@ -0,0 +1,115 @@
<?php
/**
* IP Geo Block - DNS lookup
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2016-2019 tokkonopapa
*/
class IP_Geo_Block_Lkup {
/**
* Converts IP address to in_addr representation
*
* @link https://stackoverflow.com/questions/14459041/inet-pton-replacement-function-for-php-5-2-17-in-windows
*/
private static function inet_pton( $ip ) {
// available on Windows platforms after PHP 5.3.0, need IPv6 support by PHP
if ( function_exists( 'inet_pton' ) && ( $ip = @inet_pton( $ip ) ) )
return $ip;
// ipv4
elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
if ( FALSE === strpos( $ip, ':' ) ) {
$ip = pack( 'N', ip2long( $ip ) );
}
else {
$ip = explode( ':', $ip );
$ip = pack( 'N', ip2long( $ip[ count( $ip ) - 1 ] ) );
}
}
// ipv6
elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
$ip = explode( ':', $ip );
$parts = 8 - count( $ip );
$res = '';
$replaced = 0;
foreach ( $ip as $seg ) {
if ( $seg != '' ) {
$res .= str_pad( $seg, 4, '0', STR_PAD_LEFT );
}
elseif ( $replaced == 0 ) {
for ( $i = 0; $i <= $parts; ++$i ) {
$res .= '0000';
}
$replaced = 1;
}
elseif ( $replaced == 1 ) {
$res .= '0000';
}
}
$ip = pack( 'H' . strlen( $res ), $res );
}
return $ip;
}
/**
* DNS lookup
*
*/
public static function gethostbyaddr( $ip ) {
// array( 'nameservers' => array( '8.8.8.8', '8.8.4.4' ) ) // Google public DNS
// array( 'nameservers' => array( '1.1.1.1', '1.0.0.1' ) ) // APNIC public DNS
$servers = array( 'nameservers' => apply_filters( IP_GEO_BLOCK::PLUGIN_NAME . '-dns', array() ) );
if ( ! empty( $servers['nameservers'] ) ) {
set_include_path( IP_GEO_BLOCK_PATH . 'includes' . PATH_SEPARATOR . get_include_path() );
require_once IP_GEO_BLOCK_PATH . 'includes/Net/DNS2.php';
$r = new Net_DNS2_Resolver( $servers );
try {
$result = $r->query( $ip, 'PTR' );
}
catch ( Net_DNS2_Exception $e ) {
$result = $e->getMessage();
}
if ( isset( $result->answer ) ) {
foreach ( $result->answer as $obj ) {
if ( 'PTR' === $obj->type ) {
return $obj->ptrdname;
}
}
}
}
// available on Windows platforms after PHP 5.3.0
if ( function_exists( 'gethostbyaddr' ) )
$host = @gethostbyaddr( $ip );
// if not available
if ( empty( $host ) && function_exists( 'dns_get_record' ) ) {
// generate in-addr.arpa notation
if ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
$ptr = implode( ".", array_reverse( explode( ".", $ip ) ) ) . ".in-addr.arpa";
}
elseif ( FALSE !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
$ptr = self::inet_pton( $ip );
$ptr = implode(".", array_reverse( str_split( bin2hex( $ptr ) ) ) ) . ".ip6.arpa";
}
if ( isset( $ptr ) and $ptr = @dns_get_record( $ptr, DNS_PTR ) ) {
return $ptr[0]['target'];
}
}
return empty( $host ) ? $ip : $host;
}
}

View File

@@ -0,0 +1,160 @@
<?php
/**
* IP Geo Block - Register all actions and filters for the plugin
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2016-2019 tokkonopapa
*/
/**
* Register all actions and filters for the plugin.
*
* Maintain a list of all hooks that are registered throughout
* the plugin, and register them with the WordPress API. Call the
* run function to execute the list of actions and filters.
*/
class IP_Geo_Block_Loader {
/**
* The array of actions registered with WordPress.
*
* @since 3.0.0
* @access protected
* @var array $actions The actions registered with WordPress to fire when the plugin loads.
*/
protected $actions;
/**
* The array of filters registered with WordPress.
*
* @since 3.0.0
* @access protected
* @var array $filters The filters registered with WordPress to fire when the plugin loads.
*/
protected $filters;
/**
* Initialize the collections used to maintain the actions and filters.
*
* @since 3.0.0
*/
public function __construct() {
$this->actions = array();
$this->filters = array();
}
/**
* Add a new action to the collection to be registered with WordPress.
*
* @since 3.0.0
* @param string $hook The name of the WordPress action that is being registered.
* @param object $component A reference to the instance of the object on which the action is defined.
* @param string $callback The name of the function definition on the $component.
* @param int $priority Optional. he priority at which the function should be fired. Default is 10.
* @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1.
*/
public function add_action( $hook, $callback, $priority = 10, $accepted_args = 1 ) {
$this->actions = $this->add( $this->actions, $hook, $callback, $priority, $accepted_args );
}
/**
* Add a new filter to the collection to be registered with WordPress.
*
* @since 3.0.0
* @param string $hook The name of the WordPress filter that is being registered.
* @param object $component A reference to the instance of the object on which the filter is defined.
* @param string $callback The name of the function definition on the $component.
* @param int $priority Optional. he priority at which the function should be fired. Default is 10.
* @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1
*/
public function add_filter( $hook, $callback, $priority = 10, $accepted_args = 1 ) {
$this->filters = $this->add( $this->filters, $hook, $callback, $priority, $accepted_args );
}
public function apply_filters( $hook, $value ) {
$args = func_get_args();
foreach ( $this->filters as $index => $filter ) {
if ( $filter['hook'] === $hook ) {
$args[1] = $value;
$value = call_user_func_array(
$filter['callback'], array_slice( $args, 1, (int)$filter['accepted_args'] )
);
}
}
return $value;
}
/**
* A utility function that is used to register the actions and hooks into a single
* collection.
*
* @since 3.0.0
* @access private
* @param array $hooks The collection of hooks that is being registered (that is, actions or filters).
* @param string $hook The name of the WordPress filter that is being registered.
* @param object $component A reference to the instance of the object on which the filter is defined.
* @param string $callback The name of the function definition on the $component.
* @param int $priority The priority at which the function should be fired.
* @param int $accepted_args The number of arguments that should be passed to the $callback.
* @return array The collection of actions and filters registered with WordPress.
*/
private function add( $hooks, $hook, $callback, $priority, $accepted_args ) {
$hooks[] = array(
'hook' => $hook,
'callback' => $callback,
'priority' => $priority,
'accepted_args' => $accepted_args
);
return $hooks;
}
/**
* Register the filters and actions with WordPress.
*
* @since 3.0.0
*/
public function run() {
/**
* This part will be executed after loading this plugin.
* Register all the rest of the action and filter hooks.
*/
if ( IP_Geo_Block_Util::is_user_logged_in() ) {
foreach ( $this->actions as $index => $hook ) {
add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
unset( $this->actions[ $index ] );
}
}
/**
* This part will be executed at the very beginning of WordPress core.
* Execute callbacks that are specified by the component with 'init'.
*/
elseif ( defined( 'WP_ADMIN' ) && WP_ADMIN ) {
// admin ajax/post needs to be deferred
foreach ( $this->actions as $index => $hook ) {
add_action( $hook['hook'], $hook['callback'], $hook['priority'], $hook['accepted_args'] );
unset( $this->actions[ $index ] );
}
}
else {
// Execute callback directly
foreach ( $this->actions as $index => $hook ) {
call_user_func( $hook['callback'], $hook['accepted_args'] );
unset( $this->actions[ $index ] );
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,575 @@
<?php
/**
* IP Geo Block - Options
*
* @package IP_Geo_Block
* @author tokkonopapa <tokkonopapa@yahoo.com>
* @license GPL-3.0
* @link https://www.ipgeoblock.com/
* @copyright 2013-2019 tokkonopapa
*/
class IP_Geo_Block_Opts {
/**
* Default values of option table to be cached into options database table.
*
*/
private static $option_table = array(
'version' => '3.0.17',// Version of this table (not package)
// since version 1.0
'providers' => array(), // List of providers and API keys
'comment' => array( // Message on the comment form
'pos' => 0, // Position (0:none, 1:top, 2:bottom)
'msg' => NULL, // Message text on comment form
),
'matching_rule' => -1, // -1:neither, 0:white list, 1:black list
'white_list' => NULL, // Comma separeted country code
'black_list' => 'ZZ', // Comma separeted country code
'timeout' => 30, // Timeout in second
'response_code' => 403, // Response code
'save_statistics' => TRUE, // Record validation statistics
'clean_uninstall' => TRUE, // Remove all savings from DB
'simulate' => FALSE, // just simulate, never block
// since version 1.1
'cache_hold' => TRUE, // Record IP address cache
'cache_time' => HOUR_IN_SECONDS, // @since 3.5
// since version 3.0.0
'cache_time_gc' => 900, // Cache garbage collection time
'request_ua' => NULL, // since version 3.0.7
// since version 1.2, 1.3
'login_fails' => -1, // Limited number of login attempts
'validation' => array( // Action hook for validation
'comment' => FALSE, // Validate on comment post
'login' => 1, // Validate on login
'admin' => 1, // Validate on admin (1:country 2:ZEP)
'ajax' => 0, // Validate on ajax/post (1:country 2:ZEP)
'xmlrpc' => 1, // Validate on xmlrpc (1:country 2:close)
'proxy' => NULL, // $_SERVER variables for IPs
'reclogs' => 1, // 1:blocked 2:passed 3:unauth 4:auth 5:all 6:blocked/passed
'postkey' => 'action,comment,log,pwd,FILES', // Keys in $_POST, $_FILES
// since version 1.3.1
'maxlogs' => 500, // Max number of rows for validation logs
'backup' => NULL, // Absolute path to directory for backup logs
// since version 3.0.13
'explogs' => 7, // expiration time for logs [days]
// since version 2.1.0
'plugins' => 0, // Validate on wp-content/plugins (1:country 2:ZEP)
'themes' => 0, // Validate on wp-content/themes (1:country 2:ZEP)
// since version 2.2.9
'timing' => 0, // 0:init, 1:mu-plugins, 2:drop-in
'recdays' => 30, // Number of days for validation statistics
// since version 3.0.0
'includes' => 3, // for wp-includes/
'uploads' => 3, // for UPLOADS/uploads
'languages' => 3, // for WP_CONTENT_DIR/language
'public' => 0, // Validate on public facing pages
// since version 3.0.3
'restapi' => 3, // for get_rest_url()
'mimetype' => 0, // 0:disable, 1:white_list, 2:black_list
// since version 3.0.18
'metadata' => FALSE,
),
'update' => array( // Updating IP address DB
'auto' => TRUE, // Auto updating of DB files
'retry' => 0, // Number of retry to download
'cycle' => 30, // Updating cycle (days)
),
// since version 3.0.9, 3.0.17
'priority' => array( 0, PHP_INT_MAX ), // 0:high, 1:low
// since version 2.2.0
'anonymize' => TRUE, // Anonymize IP address to hide privacy
'signature' => '../,/wp-config.php,/passwd', // malicious signature
'extra_ips' => array( // Additional IP validation
'white_list' => NULL, // White list of IP addresses
'black_list' => NULL, // Black list of IP addresses
),
'rewrite' => array( // Apply rewrite rule
'plugins' => FALSE, // for wp-content/plugins
'themes' => FALSE, // for wp-content/themes
// since version 3.0.0
'includes' => FALSE, // for wp-includes/
'uploads' => FALSE, // for UPLOADS/uploads
'languages' => FALSE, // for wp-content/language
),
'Maxmind' => array( // Maxmind
// since version 2.2.2
'ipv4_path' => NULL, // Path to IPv4 DB file
'ipv6_path' => NULL, // Path to IPv6 DB file
// since version 2.2.1
'ipv4_last' => 0, // Last-Modified of DB file
'ipv6_last' => 0, // Last-Modified of DB file
// since version 3.0.4
'use_asn' => -1, // -1:install, 0:disable, 1:enable
'asn4_path' => NULL, // AS Number for IPv4
'asn6_path' => NULL, // AS Number for IPv6
'asn4_last' => 0, // AS Number for IPv4
'asn6_last' => 0, // AS Number for IPv6
),
'IP2Location' => array( // IP2Location
// since version 2.2.2
'ipv4_path' => NULL, // Path to IPv4 DB file
'ipv6_path' => NULL, // Path to IPv6 DB file
// since version 2.2.1
'ipv4_last' => 0, // Last-Modified of DB file
'ipv6_last' => 0, // Last-Modified of DB file
),
// since version 3.0.8
'Geolite2' => array( // Maxmind
'use_asn' => -1, // -1:install, 0:disable, 1:enable
'ip_path' => NULL, // GeoLite2 DB: Path
'ip_last' => NULL, // GeoLite2 DB: Last-Modified
'asn_path' => NULL, // GeoLite2 ASN DB: Path
'asn_last' => NULL, // GeoLite2 ASN DB: Last-Modified
),
// since version 2.2.3
'api_dir' => NULL, // Path to geo-location API
// since version 2.2.5
'exception' => array( // list of exceptional
'plugins' => array(), // for pliugins
'themes' => array(), // for themes
// since version 3.0.0
'admin' => array(), // for wp-admin
'public' => array( // for public facing pages
'bbp-new-topic', 'bbp-edit-topic',
'bbp-new-reply', 'bbp-edit-reply',
),
'includes' => array(), // for wp-includes/
'uploads' => array(), // for UPLOADS/uploads
'languages' => array(), // for wp-content/language
// since version 3.0.3
'restapi' => array(), // for get_rest_url()
),
// since version 2.2.7
'api_key' => array( // API key
'GoogleMap' => NULL, // 'default':revoked, NULL:iframe
),
// since version 2.2.8
'login_action' => array( // Actions for wp-login.php
'login' => TRUE,
'register' => TRUE,
'resetpass' => TRUE,
'lostpassword' => TRUE,
'postpass' => TRUE,
),
// since version 3.0.0
'response_msg' => 'Sorry, your request cannot be accepted.', // message on blocking
'redirect_uri' => 'http://blackhole.webpagetest.org/', // redirection on blocking
'network_wide' => FALSE, // settings page on network dashboard
'public' => array(
'matching_rule' => -1, // -1:follow, 0:white list, 1:black list
'white_list' => NULL, // Comma separeted country code
'black_list' => 'ZZ', // Comma separeted country code
'target_rule' => 0, // 0:all requests, 1:specify the target
'target_pages' => array(), // blocking target of pages
'target_posts' => array(), // blocking target of post types
'target_cates' => array(), // blocking target of categories
'target_tags' => array(), // blocking target of tags
'ua_list' => "Google:HOST,bot:HOST,slurp:HOST\nspider:HOST,archive:HOST,*:FEED\nembed.ly:HOST,Twitterbot:US,Facebot:US",
// since version 3.0.3
'dnslkup' => FALSE, // use DNS reverse lookup
'response_code' => 307, // better for AdSense
'redirect_uri' => NULL, // home
'response_msg' => 'Sorry, your request cannot be accepted.', // message on blocking
// since version 3.0.10
'behavior' => FALSE // Bad behavior
),
// since version 3.0.3
'mimetype' => array(
'white_list' => array(), // key and value
'black_list' => "asp,aspx,cgi,exe,js,jsp,php,php3,php4,php5,pl,py,pht,phtml,html,htm,shtml,htaccess,sh,svg,gz,zip,rar,tar", // comma separated extension
// since version 3.0.4
'capability' => array( 'upload_files' ),
),
// since version 3.0.5
'live_update' => array(
'in_memory' => 0, // -1:unavailable, 0:file, 1:memory
),
// since version 3.0.10
'behavior' => array(
'view' => 7, // More than 7 page view in 5 seconds
'time' => 5, // More than 7 page view in 5 seconds
),
// since version 3.0.13
'restrict_api' => TRUE, // Do not send IP address to external APIs
// since version 3.0.14
'login_link' => array(
'link' => NULL, // key of login link
'hash' => NULL, // hash of 'link'
),
// since version 3.0.18
'monitor' => array(
'updated_option' => FALSE,
'update_site_option' => FALSE,
),
'metadata' => array(
'pre_update_option' => array( 'siteurl', 'admin_email', 'users_can_register', 'default_role' ), // @since 2.0.0 `manage_options`
'pre_update_site_option' => array( 'siteurl', 'admin_email', 'registration' ), // @since 3.0.0 `manage_network_options`
),
);
/**
* I/F for option table
*
*/
public static function get_default() {
// https://developer.wordpress.org/reference/functions/wp_get_mime_types/
// https://codex.wordpress.org/Uploading_Files#About_Uploading_Files_on_Dashboard
self::$option_table['mimetype']['white_list'] = array(
// Image formats.
'jpg|jpeg|jpe' => 'image/jpeg',
'gif' => 'image/gif',
'png' => 'image/png',
'ico' => 'image/x-icon',
// Video formats.
'wmv' => 'video/x-ms-wmv',
'avi' => 'video/avi',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'mp4|m4v' => 'video/mp4',
'ogv' => 'video/ogg',
'3gp|3gpp' => 'video/3gpp',
'3g2|3gp2' => 'video/3gpp2',
// Audio formats.
'mp3|m4a|m4b' => 'audio/mpeg',
'wav' => 'audio/wav',
'ogg|oga' => 'audio/ogg',
// Misc application formats.
'pdf' => 'application/pdf',
'psd' => 'application/octet-stream',
// MS Office formats.
'doc' => 'application/msword',
'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'odt' => 'application/vnd.oasis.opendocument.text',
);
return self::$option_table;
}
/**
* Upgrade option table
* @since 3.0.3.1 This should be executed in admin context
*/
public static function upgrade() {
$default = IP_Geo_Block::get_default();
$settings = IP_Geo_Block::get_option();
$version = $settings['version'];
// refresh if it's too old
if ( version_compare( $version, '2.0.0' ) < 0 )
$settings = $default;
if ( version_compare( $version, '2.1.0' ) < 0 ) {
foreach ( array( 'plugins', 'themes' ) as $tmp ) {
$settings['validation'][ $tmp ] = $default['validation'][ $tmp ];
}
}
if ( version_compare( $version, '2.2.0' ) < 0 ) {
foreach ( array( 'anonymize', 'signature', 'extra_ips', 'rewrite' ) as $tmp ) {
$settings[ $tmp ] = $default[ $tmp ];
}
foreach ( array( 'admin', 'ajax' ) as $tmp ) {
if ( $settings['validation'][ $tmp ] == 2 )
$settings['validation'][ $tmp ] = 3; // WP-ZEP + Block by country
}
}
if ( version_compare( $version, '2.2.1' ) < 0 ) {
foreach ( array( 'Maxmind', 'IP2Location' ) as $tmp ) {
$settings[ $tmp ] = $default[ $tmp ];
}
}
if ( version_compare( $version, '2.2.2' ) < 0 ) {
$tmp = get_option( 'ip_geo_block_statistics' );
$tmp['daystats'] = array();
IP_Geo_Block_Logs::record_stat( $tmp );
delete_option( 'ip_geo_block_statistics' ); // @since 1.2.0
foreach ( array( 'maxmind', 'ip2location' ) as $tmp ) {
unset( $settings[ $tmp ] );
}
}
if ( version_compare( $version, '2.2.3' ) < 0 )
$settings['api_dir'] = $default['api_dir'];
if ( version_compare( $version, '2.2.5' ) < 0 ) {
// https://wordpress.org/support/topic/compatibility-with-ag-custom-admin
$arr = array();
foreach ( explode( ',', $settings['signature'] ) as $tmp ) {
$tmp = trim( $tmp );
if ( 'wp-config.php' === $tmp || 'passwd' === $tmp )
$tmp = '/' . $tmp;
array_push( $arr, $tmp );
}
$settings['signature'] = implode( ',', $arr );
foreach ( array( 'plugins', 'themes' ) as $tmp ) {
$settings['exception'][ $tmp ] = $default['exception'][ $tmp ];
}
}
if ( version_compare( $version, '2.2.6' ) < 0 ) {
$settings['signature'] = str_replace( " ", "\n", $settings['signature'] );
$settings['extra_ips']['white_list'] = str_replace( " ", "\n", $settings['extra_ips']['white_list'] );
$settings['extra_ips']['black_list'] = str_replace( " ", "\n", $settings['extra_ips']['black_list'] );
foreach ( array( 'plugins', 'themes' ) as $tmp ) {
$arr = array_keys( $settings['exception'][ $tmp ] );
if ( ! empty( $arr ) && ! is_numeric( $arr[0] ) )
$settings['exception'][ $tmp ] = $arr;
}
}
if ( version_compare( $version, '2.2.7' ) < 0 )
$settings['api_key'] = $default['api_key'];
if ( version_compare( $version, '2.2.8' ) < 0 ) {
$settings['login_action'] = $default['login_action'];
// Block by country (register, lost password)
if ( 2 === (int)$settings['validation']['login'] )
$settings['login_action']['login'] = FALSE;
}
if ( version_compare( $version, '2.2.9' ) < 0 ) {
$settings['validation']['timing' ] = $default['validation']['timing' ];
$settings['validation']['recdays'] = $default['validation']['recdays'];
}
if ( version_compare( $version, '3.0.0' ) < 0 ) {
foreach ( array( 'cache_time_gc', 'response_msg', 'redirect_uri', 'network_wide', 'public' ) as $tmp ) {
$settings[ $tmp ] = $default[ $tmp ];
}
foreach ( array( 'public', 'includes', 'uploads', 'languages' ) as $tmp ) {
$settings['validation'][ $tmp ] = $default['validation'][ $tmp ];
$settings['rewrite' ][ $tmp ] = $default['rewrite' ][ $tmp ];
$settings['exception' ][ $tmp ] = $default['exception' ][ $tmp ];
}
$settings['exception']['admin'] = $default['exception']['admin'];
}
if ( version_compare( $version, '3.0.1' ) < 0 )
delete_transient( IP_Geo_Block::CACHE_NAME ); // @since 2.8
if ( version_compare( $version, '3.0.3' ) < 0 ) {
$settings['exception' ]['restapi' ] = $default['exception' ]['restapi' ];
$settings['validation' ]['restapi' ] = $default['validation']['restapi' ];
$settings['validation' ]['mimetype' ] = $default['validation']['mimetype' ];
$settings['public' ]['redirect_uri' ] = $default['public' ]['redirect_uri' ];
$settings['public' ]['response_msg' ] = $default['public' ]['response_msg' ];
$settings['public' ]['response_code'] = $default['public' ]['response_code'];
$settings['public' ]['dnslkup' ] = TRUE;
$settings['public' ]['ua_list' ] = str_replace( '*:HOST=embed.ly', 'embed.ly:HOST', $settings['public']['ua_list'] );
$settings['login_action']['resetpass' ] = @$settings['login_action']['resetpasss'];
$settings['mimetype' ] = $default['mimetype'];
unset(
$settings['rewrite' ]['public' ], // unused @3.0.0
$settings['rewrite' ]['content' ], // unused @3.0.0
$settings['login_action']['resetpasss'] // mis-spelled
);
}
if ( version_compare( $version, '3.0.4.1' ) < 0 ) {
if ( ! isset( $settings['Maxmind']['use_asn'] ) ) {
$settings['Maxmind' ]['use_asn' ] = 0; // disable
$settings['Maxmind' ]['asn4_path' ] = $default['Maxmind' ]['asn4_path' ];
$settings['Maxmind' ]['asn4_last' ] = $default['Maxmind' ]['asn4_last' ];
$settings['Maxmind' ]['asn6_path' ] = $default['Maxmind' ]['asn6_path' ];
$settings['Maxmind' ]['asn6_last' ] = $default['Maxmind' ]['asn6_last' ];
$settings['mimetype']['capability'] = $default['mimetype']['capability'];
}
}
if ( version_compare( $version, '3.0.5' ) < 0 )
$settings['live_update'] = $default['live_update'];
if ( version_compare( $version, '3.0.8' ) < 0 ) {
$settings['timeout' ] = $default['timeout' ];
$settings['Geolite2'] = $default['Geolite2'];
$settings['Geolite2']['use_asn'] = $settings['Maxmind']['use_asn'];
}
if ( version_compare( $version, '3.0.10' ) < 0 ) {
$settings['behavior'] = $default['behavior'];
$settings['public' ]['behavior'] = $default['public']['behavior'];
}
if ( version_compare( $version, '3.0.11' ) < 0 ) {
// change the size of some database columns
$settings['cache_hold'] = $default['cache_hold'];
IP_Geo_Block_Logs::delete_tables( IP_Geo_Block::CACHE_NAME );
IP_Geo_Block_Logs::create_tables();
IP_Geo_Block_Logs::reset_sqlite_db();
}
if ( version_compare( $version, '3.0.13' ) < 0 ) {
$settings['validation' ]['maxlogs'] = $default['validation']['maxlogs'];
$settings['validation' ]['explogs'] = $default['validation']['explogs'];
$settings['restrict_api'] = $settings['anonymize'];
}
if ( version_compare( $version, '3.0.14' ) < 0 )
$settings['login_link'] = $default['login_link'];
if ( version_compare( $version, '3.0.15' ) < 0 )
IP_Geo_Block_Logs::upgrade( $version );
if ( version_compare( $version, '3.0.16' ) < 0 ) {
$settings['simulate'] = $settings['public']['simulate'];
unset( $settings['public']['simulate'] );
}
if ( version_compare( $version, '3.0.17' ) < 0 )
$settings['priority'] = $default['priority'];
if ( version_compare( $version, '3.0.18' ) < 0 ) {
$settings['validation']['metadata'] = $default['validation']['metadata'];
$settings['monitor' ] = $default['monitor' ];
$settings['metadata' ] = $default['metadata'];
IP_Geo_Block::update_metadata( NULL );
self::remove_mu_plugin( ); // remove new file
self::remove_mu_plugin(''); // remove old file
self::setup_validation_timing( $settings );
}
// update package version number
$settings['version'] = IP_Geo_Block::VERSION;
// install addons for IP Geolocation database API ver. 1.1.15 at IP Geo Block 3.0.18
$providers = IP_Geo_Block_Provider::get_addons();
if ( empty( $providers ) || ! $settings['api_dir'] || ! file_exists( $settings['api_dir'] ) || version_compare( $version, '3.0.18' ) < 0 )
$settings['api_dir'] = self::install_api( $settings );
$settings['request_ua'] = trim( str_replace( array( 'InfiniteWP' ), '', @$_SERVER['HTTP_USER_AGENT'] ) );
// update (or create if it does not exist) option table
IP_Geo_Block::update_option( $settings );
// return upgraded settings
return $settings;
}
/**
* Install / Uninstall APIs
*
*/
private static function install_api( $settings ) {
IP_Geo_Block_Cron::stop_update_db();
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
$src = IP_Geo_Block_Util::slashit( IP_GEO_BLOCK_PATH . 'wp-content/' . IP_Geo_Block::GEOAPI_NAME );
$dst = IP_Geo_Block_Util::slashit( self::get_api_dir( $settings ) );
if ( $src !== $dst ) {
$fs->exists( $dst ) or $fs->mkdir( $dst );
$result = copy_dir( $src, $dst );
if ( is_wp_error( $result ) ) {
if ( class_exists( 'IP_Geo_Block_Admin', FALSE ) ) {
IP_Geo_Block_Admin::add_admin_notice( 'error',
sprintf( __( 'Unable to write <code>%s</code>. Please check the permission.', 'ip-geo-block' ), '<code>' . $dst . '</code>' )
);
}
$dst = NULL;
}
}
IP_Geo_Block_Cron::start_update_db( $settings );
return $dst;
}
public static function uninstall_api( $settings ) {
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
return $fs->delete( self::get_api_dir( $settings ), TRUE ); // $recursive = true
}
private static function get_api_dir( $settings ) {
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
// wp-content
$dir = ( empty( $settings['api_dir'] ) || ! $fs->exists( $settings['api_dir'] ) ) ? WP_CONTENT_DIR : dirname( $settings['api_dir'] );
if ( ! $fs->is_writable( $dir ) ) {
// wp-content/uploads
$dir = wp_upload_dir();
$dir = $dir['basedir'];
if ( ! $fs->is_writable( $dir ) ) // wp-content/plugins/ip-geo-block
$dir = $fs->is_writable( IP_GEO_BLOCK_PATH ) ? IP_GEO_BLOCK_PATH : NULL;
}
return IP_Geo_Block_Util::slashit(
apply_filters( IP_Geo_Block::PLUGIN_NAME . '-api-dir', $dir )
) . IP_Geo_Block::GEOAPI_NAME; // must add `ip-geo-api` for basename
}
/**
* Activate / Deactivate Must-use plugin / Advanced cache
*
*/
private static function remove_mu_plugin( $prefix = '!' ) {
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
if ( $fs->exists( $src = WPMU_PLUGIN_DIR . '/' . $prefix . 'ip-geo-block-mu.php' ) )
return $fs->delete( $src ) ? TRUE : $src;
return TRUE;
}
public static function get_validation_timing( $prefix = '!' ) {
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
return $fs->exists( WPMU_PLUGIN_DIR . '/' . $prefix . 'ip-geo-block-mu.php' ) ? 1 : 0;
}
public static function setup_validation_timing( $settings = NULL, $prefix = '!' ) {
switch ( $settings ? (int)$settings['validation']['timing'] : 0 ) {
case 0: // init
if ( TRUE !== ( $src = self::remove_mu_plugin() ) )
return $src;
break;
case 1: // mu-plugins
$src = IP_GEO_BLOCK_PATH . 'wp-content/mu-plugins/ip-geo-block-mu.php';
$dst = WPMU_PLUGIN_DIR . '/' . $prefix . 'ip-geo-block-mu.php';
require_once IP_GEO_BLOCK_PATH . 'classes/class-ip-geo-block-file.php';
$fs = IP_Geo_Block_FS::init( __FUNCTION__ );
if ( ! $fs->is_file( $dst ) ) {
if ( ! $fs->is_dir( WPMU_PLUGIN_DIR ) && ! $fs->mkdir( WPMU_PLUGIN_DIR ) )
return $dst;
if ( ! $fs->copy( $src, $dst, TRUE ) )
return $dst;
}
break;
}
return TRUE;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff