60 ) ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { continue; } $data = gzdecode( wp_remote_retrieve_body( $response ) ); if ( $data && $wp_filesystem->put_contents( $file . '.tmp', $data ) && $wp_filesystem->move( $file . '.tmp', $file, true ) ) { return true; } } return false; } public static function client_ip() { // Behind a proxy the first forwarded address is the visitor. Only used for country, never stored. if ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { $ip = trim( explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) )[0] ); if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { return $ip; } } return isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : ''; } // Returns a two letter country code or null. public static function country() { if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) { $code = strtoupper( substr( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ), 0, 2 ) ); // Cloudflare uses XX for unknown and T1 for Tor. return preg_match( '/^[A-Z]{2}$/', $code ) && 'XX' !== $code && 'T1' !== $code ? $code : null; } if ( ! self::enabled() ) { return null; } $ip = self::client_ip(); $file = self::file(); if ( ! $ip || ! file_exists( $file ) ) { return null; } try { $reader = new \MaxMind\Db\Reader( $file ); $record = $reader->get( $ip ); $reader->close(); } catch ( \Exception $e ) { return null; } return isset( $record['country']['iso_code'] ) ? $record['country']['iso_code'] : null; } }