$_SERVER['REMOTE_ADDR'], 'proxy' => false, 'proxy_ip' => '', ); /* * This code tries to bypass a proxy and get the actual IP address of * the visitor behind the proxy. * Warning: These values might be spoofed! */ $ip_fields = array( 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR', ); $forwarded = false; foreach ( $ip_fields as $key ) { if ( true === array_key_exists( $key, $_SERVER ) ) { foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) { $ip = trim( $ip ); if ( false !== filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { $forwarded = $ip; break 2; } } } } // If we found a different IP address than REMOTE_ADDR then it's a proxy! if ( ! empty( $forwarded ) && $forwarded !== $result->ip ) { $result->proxy = true; $result->proxy_ip = $result->ip; $result->ip = $forwarded; } if ( $result->ip ) { $user_ip = $result->ip; } else { $user_ip = 'UNKNOWN'; } return apply_filters( 'hustle_user_ip', $user_ip ); } /** * Checks if the users IP address belongs to a certain country. * * @return bool */ public function get_user_country() { // check for bot if ( self::_is_crawler() ) { return false; } // Grab the users IP address $ip = self::get_user_ip(); // See if an add-on provides the country for us. $country = apply_filters( 'wpoi-get-user-country', '', $ip ); if ( empty( $country ) ) { $country = $this->get_country_from_ip( $ip ); } if ( empty( $country ) ) { $country = 'XX'; } return $country; } /** * Returns a list of available ip-resolution services. * * @return array List of available webservices. */ private function _get_geo_services() { static $geo_service = null; if ( null === $geo_service ) { $geo_service = array(); $geo_service['hostip'] = (object) array( 'label' => 'Host IP', 'url' => 'http://api.hostip.info/country.php?ip=%ip%', 'type' => 'text', ); $geo_service['geoplugin'] = (object) array( 'label' => 'GeoPlugin', 'url' => 'http://www.geoplugin.net/json.gp?ip=%ip%', 'type' => 'json', 'field' => array( 'geoplugin_countryCode' ), ); /** * Allow other modules/plugins to register a geo service. */ $geo_service = apply_filters( 'wpoi-geo-services', $geo_service ); } return $geo_service; } /** * Returns a list of deprecated geo ip-resolution services. * * @since 4.2.1 * @return array List of deprecated webservices. */ private function get_deprecated_geo_services() { $geo_service = array( 'telize', 'nekudo', ); /** * Hook to filter the list of depracated geo ip-resolution services. * * @since 4.2.1 * * @param array */ $geo_service = apply_filters( 'hustle_depracated_geo_services', $geo_service ); return $geo_service; } /** * Returns the lookup-service details * * @return object Service object for geo lookup */ private function _get_service( $type = null ) { $service = false; if ( null === $type ) { $remote_ip_url = apply_filters( 'wpoi-remote-ip-url', '' ); if ( ! empty( $remote_ip_url ) ) { $type = ''; } else { $type = self::DEFAULT_GEOIP_PROVIDER; } /** * Allow to choose a geo service. */ $type = apply_filters( 'wpoi-geo-type-service', $type ); } if ( empty( $type ) ) { $service = (object) array( 'url' => $remote_ip_url, 'label' => 'wp-config.php', 'type' => 'text', ); } elseif ( 'geo_db' === $type ) { $service = (object) array( 'url' => 'db', 'label' => __( 'Local IP Lookup Table', 'hustle' ), 'type' => 'text', ); } else { $geo_service = $this->_get_geo_services(); $deprecated_geo_service = $this->get_deprecated_geo_services(); if ( in_array( $type, $deprecated_geo_service, true ) ) { $message = sprintf( /* translators: %s: geoip provider name. */ __( 'GeoIP provider %s is no longer available. Switching to default.', 'hustle' ), $type ); _deprecated_argument( __FUNCTION__, '4.2.1', $message ); $service = $geo_service[ self::DEFAULT_GEOIP_PROVIDER ]; } else { if ( isset( $geo_service[ $type ] ) ) { $service = $geo_service[ $type ]; } else { if ( WP_DEBUG ) { $message = sprintf( /* translators: %s: geoip provider name. */ __( 'GeoIP provider %s does not exist. Switching to default.', 'hustle' ), $type ); trigger_error( $message, E_USER_NOTICE ); } $service = $geo_service[ self::DEFAULT_GEOIP_PROVIDER ]; } } } return $service; } /** * Queries an external geo-API to find the country of the specified IP. * * @param string $ip The IP Address. * @param object $service Lookup-Service details. * @return string The country code. */ private function _country_from_api( $ip, $service ) { $country = false; if ( is_object( $service ) && ! empty( $service->url ) ) { $url = str_replace( '%ip%', $ip, $service->url ); $response = wp_remote_get( $url ); if ( ! is_wp_error( $response ) ) { $body = isset( $response['body'] ) ? $response['body'] : ''; if ( ! is_wp_error( $response ) && 200 === (int) $response['response']['code'] && 'XX' !== $response['body'] || false !== ( $body = file_get_contents( $url ) ) // phpcs:ignore ) { if ( 'text' === $service->type ) { $country = trim( $body ); } elseif ( 'json' === $service->type ) { $data = (array) json_decode( $body ); if ( isset( $service->field ) ) { if ( is_array( $service->field ) ) { $keys = $service->field; $value = $data; while ( $a = array_shift( $keys ) ) { // phpcs:ignore if ( is_array( $value ) ) { if ( isset( $value[ $a ] ) ) { $value = $value[ $a ]; } } elseif ( is_object( $value ) ) { if ( isset( $value->$a ) ) { $value = $value->$a; } } if ( is_string( $value ) ) { $country = $value; } } } else { $country = isset( $data[ $service->field ] ) ? $data[ $service->field ] : null; } } } } } } return $country; } /** * Updates ip-country map and stores in options ( sitemeta ) table * * @param $ip * @param $country * @return mixed */ private function _update_ip_county_map( $ip, $country ) { $country_ip_map[ $ip ] = $country; update_option( self::COUNTRY_IP_MAP, $country_ip_map ); return $country; } /** * Retrieves ip-country map from options ( sitemeta ) table * * @return array */ private function _get_ip_county_map() { return get_option( self::COUNTRY_IP_MAP, array() ); } /** * Checks if the user is a crawler/bot. * * @return bool */ private static function _is_crawler() { if ( isset( $_SERVER['HTTP_USER_AGENT'] ) && preg_match( '/bot|crawler|ia_archiver|mediapartners-google|80legs|wget|voyager|baiduspider|curl|yahoo!|slurp/i', $_SERVER['HTTP_USER_AGENT'] ) ) { return true; } return false; } /** * Returns country string using ip address * * @param $ip * @return string */ public function get_country_from_ip( $ip ) { // check for bot if ( self::_is_crawler() ) { return false; } $ip = (string) $ip; if ( '127.0.0.1' === $ip ) { return $this->_update_ip_county_map( $ip, 'localhost' ); } $country_ip_map = $this->_get_ip_county_map(); if ( isset( $country_ip_map[ $ip ] ) ) { if ( ! empty( $country_ip_map[ $ip ] ) ) { return $country_ip_map[ $ip ]; } } $service = $this->_get_service(); $country = $this->_country_from_api( $ip, $service ); if ( ! empty( $country ) ) { return $this->_update_ip_county_map( $ip, $country ); } return 'XX'; } }